Java 包含更新图像的JScrollPane大小错误
我正在编写一个GUI,其中包含一个JScrollPane,它显示一个更新的图像(可能会修改其维度)。图像位于JLabel中的图像图标中。使用ImageIcon.getIconWith()和getIconHeight()检索图像大小。JLabel首选尺寸将使用这些尺寸进行更新 当应用程序第一次启动时,JScrollPane及其滚动条具有查看整个图像的正确尺寸(可能使用滚动)。但是,当图像更新时,JScrollPane和滚动条会假定图像具有上一个图像的尺寸。如何使JScrollPane正确更新 这是我的GUI的策划版本Java 包含更新图像的JScrollPane大小错误,java,image,swing,updates,jscrollpane,Java,Image,Swing,Updates,Jscrollpane,我正在编写一个GUI,其中包含一个JScrollPane,它显示一个更新的图像(可能会修改其维度)。图像位于JLabel中的图像图标中。使用ImageIcon.getIconWith()和getIconHeight()检索图像大小。JLabel首选尺寸将使用这些尺寸进行更新 当应用程序第一次启动时,JScrollPane及其滚动条具有查看整个图像的正确尺寸(可能使用滚动)。但是,当图像更新时,JScrollPane和滚动条会假定图像具有上一个图像的尺寸。如何使JScrollPane正确更新 这是
Visualizer.java
使用GUIVisualizerGUI.java
。按下“运行”按钮时,将使用ImageDrawer.drawImage()
(模拟实际应用程序的行为)随机生成一个新图像,并使用函数VisualizerGUI.setTransitionsImage(字符串imgPath)
更新JScrollPane的内容
Visualizer.java:
import java.util.*;
import java.io.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Visualizer implements ActionListener {
private VisualizerGUI gui = null;
public Visualizer() {
gui = VisualizerGUI.createAndStart(this);
}
public static void main(String[] args) {
Visualizer viz = new Visualizer();
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Run command")) {
run();
}
}
public void run() {
updateGUIwithSolution();
}
public void updateGUIwithSolution() {
gui.initGUIupdate();
try {
ImageDrawer.drawImage();
gui.setTransitionsImage("image.png");
} catch (Exception e) {
System.out.println("Error while generating image");
e.printStackTrace();
}
gui.finalizeGUIupdate();
}
}
VisualizerGUI.java:
import java.util.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.lang.reflect.InvocationTargetException;
public final class VisualizerGUI {
private JFrame frame;
private JButton runButton;
private JButton nextButton;
private JScrollPane transitionsDisplay;
private JTabbedPane executionsDisplay;
private JTabbedPane tracesDisplay;
private JTextArea textInfoArea;
public VisualizerGUI() {}
private void initGUI(ActionListener actionsHandler) {
//Create and set up the window.
frame = new JFrame("Visualizer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel controlPanel = new JPanel(new FlowLayout());
runButton = new JButton("Run");
runButton.addActionListener(actionsHandler);
runButton.setActionCommand("Run command");
controlPanel.add(runButton);
nextButton = new JButton("Next");
nextButton.addActionListener(actionsHandler);
nextButton.setActionCommand("Find next solution");
controlPanel.add(nextButton);
transitionsDisplay = new JScrollPane();
executionsDisplay = new JTabbedPane();
tracesDisplay = new JTabbedPane();
JSplitPane ETspliter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, executionsDisplay, tracesDisplay);
JSplitPane graphsSpliter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, transitionsDisplay, ETspliter);
textInfoArea = new JTextArea();
textInfoArea.setLineWrap(true);
textInfoArea.setWrapStyleWord(true);
textInfoArea.setEditable(false);
JScrollPane textInfoAreaSP = new JScrollPane(textInfoArea);
JSplitPane topSpliter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, graphsSpliter, textInfoAreaSP);
transitionsDisplay.setPreferredSize(new Dimension(200,200));
executionsDisplay.setPreferredSize(new Dimension(200,200));
tracesDisplay.setPreferredSize(new Dimension(200,200));
textInfoAreaSP.setPreferredSize(new Dimension(200,100));
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(controlPanel, BorderLayout.NORTH);
frame.getContentPane().add(topSpliter, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static VisualizerGUI createAndStart(ActionListener actionsHandler) {
VisualizerGUI gui = new VisualizerGUI();
final Runnable guiRunner =
new Runnable() {
public void run() {
gui.initGUI(actionsHandler);
// gui.pack();
}
};
try {
javax.swing.SwingUtilities.invokeAndWait(guiRunner);
} catch (InterruptedException e) {
System.out.println(">>> WARNING <<< InterruptedException while creating the GUI");
} catch (InvocationTargetException e) {
System.out.println(">>> WARNING <<< InvocationTargetException while creating the GUI");
}
return gui;
}
public void clear() {
initGUIupdate();
finalizeGUIupdate();
}
public void initGUIupdate() {
// frame.setVisible(false);
transitionsDisplay.setViewportView(null);
executionsDisplay.removeAll();
tracesDisplay.removeAll();
textInfoArea.setText(null);
}
public void pack() {
frame.pack();
}
public void finalizeGUIupdate() {
// frame.validate();
// frame.repaint();
// frame.setVisible(true);
}
public void setTransitionsImage(String imgPath) {
ImageIcon icon = new ImageIcon(imgPath);
icon.getImage().flush();
int width = icon.getIconWidth();
int height = icon.getIconHeight();
JLabel label = new JLabel();
label.setVerticalAlignment(SwingConstants.CENTER);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setIcon(icon);
label.setPreferredSize(new Dimension(width,height));
//label.setPreferredSize(null);
transitionsDisplay.setViewportView(label);
label.revalidate();
label.repaint();
transitionsDisplay.getViewport().revalidate();
transitionsDisplay.getViewport().repaint();
transitionsDisplay.revalidate();
// transitionsDisplay.validate();
transitionsDisplay.repaint();
frame.revalidate();
// frame.validate();
frame.repaint();
}
public void setTransitionsImageInED(String imgPath) {
final Runnable guiRunner =
new Runnable() {
public void run() { setTransitionsImage(imgPath); }
};
// javax.swing.SwingUtilities.invokeLater(guiRunner);
try {
javax.swing.SwingUtilities.invokeAndWait(guiRunner);
} catch (InterruptedException e) {
System.out.println(">>> WARNING <<< InterruptedException while creating the GUI");
} catch (InvocationTargetException e) {
System.out.println(">>> WARNING <<< InvocationTargetException while creating the GUI");
}
}
}
有人能解释一下我为什么会有这个问题吗?谢谢
transitionsDisplay.setPreferredSize(new Dimension(200,200));
executionsDisplay.setPreferredSize(new Dimension(200,200));
tracesDisplay.setPreferredSize(new Dimension(200,200));
textInfoAreaSP.setPreferredSize(new Dimension(200,100));
不要使用setPreferredSize(…)。每个Swing组件负责确定其自身的大小
使用ImageIcon.getIconWith()和getIconHeight()检索图像大小。JLabel首选尺寸将使用这些尺寸进行更新
没有必要。同样,JLabel将根据图标的大小确定自己的大小。这是在图像/图标更改时动态完成的
当标签的首选大小大于滚动窗格的大小时,滚动窗格的滚动条将出现。让布局管理器完成他们的工作。我注释掉了VisualizationRGUI.java中的5行“setPreferredSize”,删除了.class文件并重新编译。我仍然有同样的问题。第一次按下“运行”按钮(最初没有图像)时,图像居中,滚动窗格具有正确的设置。但当我再次按下“运行”按钮时,图像和滚动窗格设置的左上角位置是错误的。它们被设置为必须显示的前一个图像。
transitionsDisplay.setPreferredSize(new Dimension(200,200));
executionsDisplay.setPreferredSize(new Dimension(200,200));
tracesDisplay.setPreferredSize(new Dimension(200,200));
textInfoAreaSP.setPreferredSize(new Dimension(200,100));