我的问题与带有内部 JPanel
的 JScrollPane
有关。我尝试在 JPanel
上绘图,但它会短暂出现然后消失,直到我手动移动 HorizontalScrollBar
,然后再次出现并保持稳定。为了避免手动干预(或在实际代码中很难管理的 HorizontalScrollBar.setValue
),我在 上尝试了
、validate/revalidate
(以及更多),但没有成功。 JPanelViewport
、JScrollPane
和 JFrame
。
下面的(非常)简化的代码重现了该问题。可能是显而易见的东西,但我看不到。
public class Main {
private JFrame mainPane;
private RenderZone renderZone = new RenderZone();
private JScrollPane renderScrollPane = new JScrollPane(renderZone,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main window = new Main();
window.mainPane.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Main() {
initialize();
}
private void initialize() {
mainPane = new JFrame();
mainPane.setPreferredSize(new Dimension(1024, 768));
mainPane.setSize(new Dimension(1024, 768));
mainPane.setLocation(new Point(200, 200));
mainPane.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SpringLayout springLayout = new SpringLayout();
springLayout.putConstraint(SpringLayout.NORTH, renderScrollPane, 0, SpringLayout.NORTH, mainPane.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, renderScrollPane, 0, SpringLayout.WEST, mainPane.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, renderScrollPane, 0, SpringLayout.SOUTH, mainPane.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, renderScrollPane, 0, SpringLayout.EAST, mainPane.getContentPane());
mainPane.getContentPane().setLayout(springLayout);
mainPane.getContentPane().add(renderScrollPane);
}
public class RenderZone extends JPanel {
private static final long serialVersionUID = -8240875812801921009L;
private BufferedImage image = null;
private BufferedImage sub = null;
public RenderZone() {
this.setBackground(Color.WHITE);
this.setPreferredSize(new Dimension(1124, 768));// added 100 for test purpose
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);// pour repeindre la panel à chaque fois
Graphics2D g2 = (Graphics2D)this.getGraphics();
if(image==null) {
try {
image = ImageIO.read(RenderZone.class.getResourceAsStream("TestImage0.png"));
sub = image.getSubimage(0, 0, 1024, 768);
} catch (IOException e) {}
}
if( sub!=null)g2.drawImage(sub, 0, 0, null);
g2.dispose();
}
}
}
最佳答案
代码有一些问题,这是修复后的代码。有关说明,请参阅代码下面的要点。
public class RenderZone extends JPanel {
private static final long serialVersionUID = -8240875812801921009L;
private BufferedImage image = null;
private BufferedImage sub = null;
public RenderZone() {
this.setBackground(Color.WHITE);
this.setPreferredSize(new Dimension(1124, 768));// added 100 for test purpose
image = new BufferedImage(2000, 1000, BufferedImage.TYPE_INT_RGB);
sub = image.getSubimage(0, 0, 1024, 768);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);// pour repeindre la panel à chaque fois
if (sub != null) {
g.drawImage(sub, 0, 0, this);
}
}
}
好的..
Graphics2D g2 = (Graphics2D)this.getGraphics();
当您已经拥有有效的Graphics
实例时,很难确定为什么您认为这是一个好主意。但基本上,使用提供的Graphics
实例。ImageIO.read(..);
读取图像不应该在任何绘制方法中完成。它应该在类的构造函数中加载一次。sub = image.getSubimage(0, 0, 1024, 768);
再说一次,您不想每次调用 Paint 时都执行此操作,事实上,它会更优化在照片编辑软件中创建正确尺寸的图像,然后加载裁剪图像。} catch (IOException e) {}
不要忽略异常!他们准确地告诉我们出了什么问题。除非实现了日志记录,否则至少要调用Throwable.printStackTrace()
if( sub!=null)g2.drawImage(sub, 0, 0, null);
因为每个JComponent
都是一个ImageObserver
,应该是if( sub!=null)g2.drawImage(sub, 0, 0, this);
还有一些可疑的事情,但它们不是当前问题的一部分,因此它们没有改变:
//pour reeindre la panel à chaque fois
.. 法语中的代码注释(仅供人类使用)的意义是什么?请用英文填写代码注释(针对本网站)。否则它们就是噪音。this.setPreferredSize(new Dimension(1124, 768));
可能最好重写getPreferredSize()
并根据 (如直接从子
图像获取的数字。mainPane.setPreferredSize(new Dimension(1024, 768));
这比mainPane.pack();
更好。后者不是猜测,并且将考虑子组件的首选大小。
关于java - 内部内容在 JScrollPane 中显示然后消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51223037/