JScrollPane和图形2D [英] JScrollPane & Graphics2D
问题描述
我试图绘制比JFrame大的图形,并使用JScrollPane滚动整个图形.我创建了一个包含两行的简单示例.出现滚动条,但不显示图形.
I am trying to draw graphics that is bigger than the JFrame and use JScrollPane to scroll the entire graphics. I created a simple example with two lines. The scroll bars appear but the graphics do not show.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Test extends JPanel{
public static void main(String... args) {
Test test = new Test();
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.add(test);
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(0, 0, 1350, 700);
JPanel contentPane = new JPanel(null);
contentPane.setPreferredSize(new Dimension(1400, 700));
contentPane.add(scrollPane);
frame.setContentPane(contentPane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
@Override
protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.drawLine(30,30,30,3000);
g2.drawLine(30, 400, 500, 3000);
}
}
推荐答案
欢迎来到一个精彩的示例,说明为什么null
布局很烂...
Welcome to a wonderful example of why null
layouts suck...
避免使用null
布局,像素完美布局是现代ui设计中的一种幻觉.有太多因素会影响组件的单个大小,您无法控制. Swing旨在与布局管理者为核心一起工作,舍弃这些问题不会导致任何问题,而您将花费越来越多的时间进行纠正
Avoid using null
layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
另请参见为什么?不希望在SWING中使用空布局?以了解更多详细信息...
Also see Why is it frowned upon to use a null layout in SWING? for more details...
基本问题是JScrollPane
,有一个JViewport
,它实际上包含您的组件. JViewport
使用组件大小调整提示来确定应该多大,而JScrollPane
使用JViewport
做出的决定来确定是否需要显示滚动条.
The basic problem is, the JScrollPane
, has a JViewport
, which actually contains your component. The JViewport
uses your components sizing hints to make determinations about how big it should be and the JScrollPane
uses the decisions the JViewport
makes to make determinations about whether it needs to display the scrollbars or not.
JViewport
正在查看您的组件,并已决定(因为您没有告诉过它)它的大小应为0x0
.
The JViewport
is taking a look at your component and has decided, because you've not told it otherwise, that it should be 0x0
in size.
您可以通过在组件setBorder(new LineBorder(Color.RED));
中添加LineBorder
来证明这一点,您也不会看到它(或者,如果看到,它将是一个红色小方块)
You can prove this by adding a LineBorder
to your component, setBorder(new LineBorder(Color.RED));
, you won't see it either (or if you do, it will be a little red square)
首先要覆盖Test
面板的getPrefferedSize
方法,然后返回一些合适的大小
Start by overriding the getPrefferedSize
method of the Test
panel and return some appropriate size
接下来,在执行任何自定义绘画之前,请致电super.paintComponent
,否则您将得到一些令人敬畏但令人讨厌的绘画瑕疵...
Next, call super.paintComponent
before you perform any custom painting, otherwise you'll end up with some awesome, but annoying, paint artifacts...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test extends JPanel {
public static void main(String... args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Test test = new Test();
JFrame frame = new JFrame();
JScrollPane scrollPane = new JScrollPane(test);
frame.add(scrollPane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(3000, 3000);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawLine(30, 30, 30, 3000);
g2.drawLine(30, 400, 500, 3000);
}
}
You'll probably want to take a look at the Scrollable
interface
next, so you can control the default size of the JViewport
, so it won't try and fill the entire screen.
看看实现精通滚动滚动的客户端了解更多信息
这篇关于JScrollPane和图形2D的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!