【问题标题】:Java: Swing component(s) not repaintingJava:Swing 组件不重绘
【发布时间】:2014-03-01 05:50:27
【问题描述】:

我正在使用 Java 网站上的一些示例代码,文件选择器似乎得到了我想要的文件,但是当我尝试更新我曾经调用文件选择器的 gui 中的 jframe 和其他组件时,什么也没有变化。我已经尝试了很多建议的修复程序来更新内容,但似乎没有任何效果。顺便说一句,我的大部分组件都是静态的......

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.awt.event.*;

public class GuiTester extends JFrame {

    private static String fileName = "Input File: Please select a file";
    //Create a file chooser
    private static final JFileChooser fc = new JFileChooser();
    private static JButton inputSelectorButton;
    private static JButton outputSelectorButton;
    private static JFrame frame = new JFrame( "Gui Tester" );
    private static JPanel panel = new JPanel();
    private static JLabel inputFile = new JLabel( fileName );


    public static void main(String[] args) {
        go();
    }


    private static void go() {
        inputSelectorButton = new JButton ( "Select Input File" );
        outputSelectorButton = new JButton ( "Select Output File" );
        Font bigFont = new Font( "sans", Font.BOLD, 22 );
        Font smallFont = new Font( "sans", Font.PLAIN, 9 );
        panel.setLayout(new BoxLayout( panel, BoxLayout.Y_AXIS ) );
        JLabel description0 = new JLabel(" ");        
        JLabel description6 = new JLabel(" ");
        JLabel inputFile = new JLabel( fileName );
        inputFile.setFont( smallFont );
        inputSelectorButton.addActionListener( new inputSelectorListener() );
        JButton startButton = new JButton ( "GO!" );

        panel.add(description0);
        panel.add(description6);
        panel.add( inputFile );
        panel.add( inputSelectorButton );
        panel.add( outputSelectorButton );
        panel.add( startButton );

        frame.getContentPane().add( BorderLayout.CENTER, panel );
        inputFile.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        inputSelectorButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        outputSelectorButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        startButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        frame.setSize(370,400);
        panel.setSize(370,400);

        frame.setVisible(true);
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    }


    public static class inputSelectorListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == inputSelectorButton) {
                int returnVal = fc.showOpenDialog( panel );

                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = fc.getSelectedFile();
                    if ( file.exists() )
                        fileName = file.getPath();
                    else
                        fileName = "File not found, please select a file";
                    System.out.println(fileName);
                    inputFile.setText( fileName );
                    inputFile.validate();
                    inputFile.repaint();
                    panel.validate();
                    panel.repaint();
                    frame.validate();
                    frame.repaint();
                } else {
                    System.out.println("Open command cancelled by user.");
                }
            }
        }
    }

}

【问题讨论】:

  • 可能是因为您拥有的引用不是屏幕上的引用,但这只是猜测,因为您未能提供一个可运行的示例来证明您的问题...
  • 如需尽快获得更好的帮助,请发帖Minimal Complete Tested and Readable Example (MCTRE)。
  • @AndrewThompson 完成。
  • @MadProgrammer,抱歉,已修复。
  • 小心过度使用static,它不是你的朋友...

标签: java swing repaint


【解决方案1】:

您应该尝试使用类并更好地组织您的代码。下面我重新设计了您现有的代码。我没有添加任何东西,但我确实移动了一些东西,并为这个示例删除了几个不必要的变量。

我将您的 ActionListener 更改为 AbstractAction,只是为了让您知道。 :-p

import java.awt.Container;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.io.File;

import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class GuiTester extends JPanel {

    // Create a file chooser
    private static final JFileChooser fc = new JFileChooser();

    private JLabel inputFile;

    public GuiTester(int width, int height) {
        Font smallFont = new Font("sans", Font.PLAIN, 9);
        JLabel description0 = new JLabel(" ");
        JLabel description6 = new JLabel(" ");
        JButton startButton = new JButton("Enter");
        JButton inputSelectorButton = new JButton(new FileChooserAction(
                "Select Input File"));
        JButton outputSelectorButton = new JButton("Select Output File");

        inputFile = new JLabel("Input File: Please select a file");
        inputFile.setFont(smallFont);

        inputFile.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        inputSelectorButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        outputSelectorButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        startButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);

        add(description0);
        add(description6);
        add(inputFile);
        add(inputSelectorButton);
        add(outputSelectorButton);
        add(startButton);

        setSize(width, height);
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    }

    public JLabel getInputFileLabel() {
        return inputFile;
    }

    @Override
    public void invalidate() {
        super.invalidate();

        // Invalidate the label, you really don't need this, but you should
        // reference children in here if you want to explicitly invalidate them
        // when the parent gets invalidated. The parent is responsible for
        // telling its children what to do and when to do it.
        inputFile.invalidate();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // This gets called when you repaint, since you are adding children
        // to this panel, painting is pointless. You can however fill the
        // background if you wish.
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame("Gui Test");

                f.setContentPane(new GuiTester(370, 400));
                f.setSize(370, 400);
                f.setVisible(true);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationRelativeTo(null);
            }
        });
    }

    public class FileChooserAction extends AbstractAction {
        public FileChooserAction(String name) {
            super(name);
        }

        public void actionPerformed(ActionEvent e) {
            Container c = ((JButton) e.getSource()).getParent();
            GuiTester g = null;

            if (c instanceof GuiTester) {
                g = (GuiTester) c;
            }

            int returnVal = fc.showOpenDialog(c);

            if (g != null && returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                String fileName = "Input File: Please select a file";

                if (file.exists())
                    fileName = file.getPath();
                else
                    fileName = "File not found, please select a file";

                System.out.println(fileName);

                g.getInputFileLabel().setText(fileName);

                g.validate();
                g.repaint();
            } else {
                System.out.println("Open command cancelled by user.");
            }
        }
    }
} 

【讨论】:

  • 不需要覆盖invalidate,因为它会标记需要自动重新布局的组件层次结构
  • 谢谢@Mr.Polywhirl 我会看看这个,看看我能不能学到一些东西!
【解决方案2】:

我没有看到你添加的任何地方

  • inputFile
  • panel

任何可显示的东西。

你也在关注inputFile

您创建了一个static 引用...

private static JLabel inputFile = new JLabel(fileName);

然后在go 中,创建一个本地引用...

JLabel inputFile = new JLabel(fileName);

这意味着您在 actionPerformed 方法中使用的引用与屏幕上的引用不同。

不要依赖static来解决参考问题,这会更快地咬你,然后你就会意识到......

你可能想看看:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 2011-08-13
    • 2021-07-15
    • 2016-01-28
    相关资源
    最近更新 更多