我正在编写一个包含JScrollPane的GUI,该GUI显示一个更新的图像(可能会修改其尺寸)。该图像位于JLabel中的ImageIcon中。使用ImageIcon.getIconWith()和getIconHeight()检索图像大小。 JLabel首选尺寸会根据这些尺寸进行更新。
首次启动应用程序时,JScrollPane及其滚动条具有正确的尺寸以查看整个图像(可能使用滚动)。但是当图像更新时,JScrollPane和滚动条假设图像具有前一图像的尺寸。如何让JScrollPane正确更新?
这是我的GUI的策划版本。 Visualizer.java
使用GUI VisualizerGUI.java
。按下“运行”按钮时,将使用ImageDrawer.drawImage()
随机生成新图像(模拟实际应用程序的行为),并使用函数VisualizerGUI.setTransitionsImage(String 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");
}
}
}
ImageDrawer.java:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageDrawer {
public static void drawImage() throws Exception {
try {
int width = 20 + (int)(Math.random() * 1000);
int height = 20 + (int)(Math.random() * 1000);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D ig2 = bi.createGraphics();
ig2.setPaint(Color.blue);
ig2.fillRect(0, 0, width, height);
ig2.setPaint(Color.red);
ig2.fillRect(5, 5, width - 10, height - 10);
ig2.setPaint(Color.blue);
ig2.drawLine(0, 0, width, height);
ig2.drawLine(0, height, width, 0);
ImageIO.write(bi, "PNG", new File("image.png"));
} catch (IOException ie) {
ie.printStackTrace();
}
}
}
有人可以解释为什么我有这个问题吗?谢谢!
答案 0 :(得分:2)
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将再次根据Icon的大小确定自己的大小。这是在图像/图标改变时动态完成的。
当标签的首选大小大于滚动窗格的大小时,将显示滚动窗格的滚动条。让布局经理完成他们的工作。