2017-11-17 4 views
0

Ich kodiere eine GUI, die ein JScrollPane enthält, das ein Bild anzeigt, das aktualisiert wird (mit möglicher Änderung seiner Abmessungen). Das Bild befindet sich in einem ImageIcon in einem JLabel. Die Bildgröße wird mit ImageIcon.getIconWith() und getIconHeight() abgerufen. Und die bevorzugte Größe von JLabel wird mit diesen Dimensionen aktualisiert.Falsche Größe mit JScrollPane mit aktualisiertem Bild

Wenn die Anwendung zum ersten Mal gestartet wird, haben JScrollPane und seine Bildlaufleisten die richtigen Abmessungen, um das gesamte Bild anzuzeigen (möglicherweise mit Bildlauf). Wenn das Bild jedoch aktualisiert wird, nehmen das JScrollPane und die Bildlaufleisten an, dass das Bild die Abmessungen des vorherigen Bilds aufweist. Wie bekomme ich die JScrollPane korrekt aktualisiert?

Hier ist eine kuratierte Version meiner GUI. Visualizer.java verwendet die GUI VisualizerGUI.java. Wenn der "Ausführen" -Knopf gedrückt wird, wird ein neues Bild zufällig erzeugt unter Verwendung von ImageDrawer.drawImage() (simuliert das Verhalten der realen Anwendung) und der Inhalt des JScrollPane wird unter Verwendung der Funktion VisualizerGUI.setTransitionsImage(String imgPath) aktualisiert.

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(); 
    } 
    } 
} 

Kann jemand erklären, warum ich dieses Problem? Vielen Dank!

Antwort

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)); 

Verwenden Sie nicht setPreferredSize (...). Jede Swing-Komponente ist für die Bestimmung ihrer eigenen Größe verantwortlich.

Die Bildgröße wird mit ImageIcon.getIconWith() und getIconHeight() abgerufen. Und die bevorzugte Größe von JLabel wird mit diesen Dimensionen aktualisiert.

Nicht erforderlich. Auch hier bestimmt JLabel seine Größe basierend auf der Größe des Icons. Dies geschieht dynamisch, wenn sich das Bild/Symbol ändert.

Die Bildlaufleisten der Bildlaufleiste werden angezeigt, wenn die bevorzugte Größe der Beschriftung größer als die Größe der Bildlaufleiste ist. Lassen Sie die Layout-Manager einfach ihre Arbeit machen.

+0

Ich habe die 5 "setPreferredSize" Zeilen in VisualizerGUI.java auskommentiert, die .class-Dateien entfernt und neu kompiliert. Ich habe immer noch das gleiche Problem. Das erste Mal, wenn ich den "Run" -Knopf drücke (es gibt zu Beginn kein Bild), wird das Bild zentriert und der ScrollPane hat die richtige Einstellung. Aber wenn ich den "Run" -Button erneut drücke, sind die obere linke Position des Bildes und das ScrollPane-Setup falsch. Sie werden so eingerichtet, als wäre es das vorherige Bild, das angezeigt werden musste. – Gus