【问题标题】:Repaint only a specific JPanel inside a JFrame仅重绘 JFrame 内的特定 JPanel
【发布时间】:2014-03-28 02:36:00
【问题描述】:

我正在尝试为panel_1 JPanel 创建一个绘制组件,但我不知道该怎么做。这是我的课。

此代码有效,只是它不绘制panel_1。 如果我尝试将其添加到面板而不绘制它,它工作得很好。 我还需要该面板以给定的时间间隔自动刷新(重绘)。 请帮助我。 :D

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

public class GUI extends JFrame implements ActionListener {

    private JPanel contentPane;
    private JTextField textField;
    private JTextField textField_1;
    private JTextField textField_2;
    private JTextField textField_3;
    private JButton btnStop, btnStart;
    private JComboBox comboBox_1, comboBox;
    private Manager manager = new Manager();
    private String arrMin, arrMax, svcMin, svcMax, simTime;
    private JTextField textField_4;
    private JPanel panel_1 = new JPanel(){
        @Override
        public void paintComponent(Graphics g){

        paintComponents(g);
         panel_1.setBackground(Color.orange);
         panel_1.setVisible(true);

          System.out.println("Just testing");
        }
    };

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GUI frame = new GUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public GUI() {
        setResizable(false);
        setForeground(Color.DARK_GRAY);
        setBackground(Color.DARK_GRAY);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 700, 500);
        contentPane = new JPanel();
        contentPane.setForeground(Color.DARK_GRAY);
        contentPane.setBackground(Color.DARK_GRAY);
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JPanel panel = new JPanel();
        panel.setBounds(12, 12, 434, 346);
        panel.setForeground(Color.LIGHT_GRAY);
        contentPane.add(panel);
        panel.setLayout(null);

        JLabel lblArrivingTime = new JLabel("Arriving time");
        lblArrivingTime.setBounds(12, 367, 94, 15);
        lblArrivingTime.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblArrivingTime);

        JLabel lblMin = new JLabel("Min");
        lblMin.setBounds(12, 395, 70, 15);
        lblMin.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblMin);

        JLabel lblMax = new JLabel("Max");
        lblMax.setBounds(12, 418, 70, 15);
        lblMax.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblMax);

        textField = new JTextField();
        textField.setBounds(58, 394, 48, 16);
        contentPane.add(textField);
        textField.setColumns(10);

        textField_1 = new JTextField();
        textField_1.setBounds(58, 422, 48, 15);
        contentPane.add(textField_1);
        textField_1.setColumns(10);

        JLabel lblServiceTime = new JLabel("Service Time");
        lblServiceTime.setBounds(152, 367, 105, 15);
        lblServiceTime.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblServiceTime);

        JLabel lblMin_1 = new JLabel("Min");
        lblMin_1.setBounds(152, 395, 51, 15);
        lblMin_1.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblMin_1);

        JLabel lblMax_1 = new JLabel("Max");
        lblMax_1.setBounds(152, 418, 70, 15);
        lblMax_1.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblMax_1);

        textField_2 = new JTextField();
        textField_2.setBounds(209, 393, 48, 17);
        contentPane.add(textField_2);
        textField_2.setColumns(10);

        textField_3 = new JTextField();
        textField_3.setBounds(209, 417, 48, 17);
        contentPane.add(textField_3);
        textField_3.setColumns(10);

        JLabel lblSimSetup = new JLabel("Sim. Setup");
        lblSimSetup.setBounds(292, 367, 94, 15);
        lblSimSetup.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblSimSetup);

        JLabel lblQueue = new JLabel("Queue");
        lblQueue.setBounds(292, 395, 70, 15);
        lblQueue.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblQueue);

        String[] numbers = { "1", "2", "3", "4" };
        comboBox = new JComboBox(numbers);
        comboBox.setBounds(345, 395, 75, 15);
        contentPane.add(comboBox);

        JLabel lblMode = new JLabel("Mode");
        lblMode.setBounds(292, 418, 70, 15);
        lblMode.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblMode);

        String[] mode = { "Time", "Number" };
        comboBox_1 = new JComboBox(mode);
        comboBox_1.setBounds(345, 413, 75, 15);
        contentPane.add(comboBox_1);

        JLabel lblActions = new JLabel("Actions");
        lblActions.setBounds(484, 367, 70, 15);
        lblActions.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblActions);

        btnStart = new JButton("Start");
        btnStart.setBounds(482, 392, 81, 20);
        contentPane.add(btnStart);

        btnStop = new JButton("Stop");
        btnStop.setBounds(482, 415, 81, 20);
        contentPane.add(btnStop);

        JLabel lblTime = new JLabel("Time");
        lblTime.setBounds(292, 440, 70, 15);
        lblTime.setForeground(Color.LIGHT_GRAY);
        contentPane.add(lblTime);

        textField_4 = new JTextField();
        textField_4.setBounds(345, 438, 75, 17);
        contentPane.add(textField_4);
        textField_4.setColumns(10);



        panel_1.setBounds(484, 12, 202, 346);
        contentPane.add(panel_1);
        panel_1.setLayout(null);

        JTextArea textArea = new JTextArea();
        textArea.setBounds(158, 12, -126, 322);
        panel_1.add(textArea);

        btnStop.addActionListener(this);
        btnStart.addActionListener(this);
        comboBox.addActionListener(this);
        comboBox_1.addActionListener(this);


    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == btnStop) {
            this.dispose();
            System.exit(NORMAL);
        } else if (e.getSource() == btnStart) {
            String nrQueues = (String) comboBox.getSelectedItem();
            arrMin = textField.getText();
            arrMax = textField_1.getText();
            svcMin = textField_2.getText();
            svcMax = textField_3.getText();
            simTime = textField_4.getText();
            int aMin = 0;
            int aMax = 0;
            int sMin = 0;
            int sMax = 0;
            int sTime = 0;
            int nQueues = 1;
            try {
                nQueues = Integer.parseInt(nrQueues);
                aMin = Integer.parseInt(arrMin);
                aMax = Integer.parseInt(arrMax);
                sMin = Integer.parseInt(svcMin);
                sMax = Integer.parseInt(svcMax);
                sTime = Integer.parseInt(simTime);
            } catch (NumberFormatException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            String s = (String) comboBox_1.getSelectedItem();
            System.out.println("Selected: " + s);
            boolean mode = true;
            if (s.equals("Time")) {
                mode = true;
            } else {
                mode = false;
            }
            manager.startSimulation(aMin * 1000, aMax * 1000, sMin * 1000,
                    sMax * 1000, sTime * 1000, nQueues, mode);

        }
    }

}

当然,处理程序在这种情况下不相关,因为我只对绘制该面板感兴趣。

【问题讨论】:

    标签: java swing jframe jpanel repaint


    【解决方案1】:

    首先,这个...

    private JPanel panel_1 = new JPanel(){
        @Override
        public void paintComponent(Graphics g){
            paintComponents(g);
            panel_1.setBackground(Color.orange);
            panel_1.setVisible(true);
    
            System.out.println("Just testing");
        }
    };
    

    不是自定义绘画的用途。永远不要从任何绘制方法中更改组件或任何组件的状态。

    这可能会触发一个新的重绘请求,这将使您进入一个永无止境的绘画循环......

    调用paintComponents(g); 将产生StackOverflowException。你不应该以任何方式打电话给paintComponents(注意最后的s),但你应该打电话给super.paintComponent(g);

    JPanel 默认可见。

    就目前而言,您根本不需要做任何事情......

    不要使用null 布局。 Swing 旨在与布局管理器一起使用,如果没有它们,您将无法更新屏幕,此外,像素完美布局是现代用户界面设计中的一种错觉,您无法控制字体、渲染管道或其他目标系统的各个方面可能会影响文本等大型元素的呈现方式。

    查看Laying Out Components Within a Container了解更多详情

    【讨论】:

      【解决方案2】:

      您在 paintComponent 覆盖内调用 super.paintComponents 方法。哎呀。您还使用空布局,不应该。

      您正在设置背景颜色,但没有对其进行任何操作。您应该改为在 JPanel 对象上设置背景颜色,而不是在它的 paintComponent 方法中。

      即这里

        panel_1.setBackground(Color.orange); // here
        // !! panel_1.setBounds(484, 12, 202, 346); // you shouldn't need this!
        contentPane.add(panel_1);
      

      编辑
      你说:

      简单地在文本区域附加一个字符串就可以了,它会自动显示在屏幕上吗?

      可以,只要您考虑到 Swing 线程规则。

      【讨论】:

      • 我知道我可以简单地做到这一点,但我想使用paint方法,因为在该文本区域中我将显示一个日志文件,该文件需要每秒更新一次。只是简单地在文本区域附加一个字符串就够了,它会自动显示在屏幕上吗?
      • @user2448690:对不起,我正在努力理解这一点,但无法理解它。绘制包含 JTextArea 的 JPanel 与每秒在 JTextArea 中获取更新有什么关系?我看不出这两者是如何联系起来的。
      • 好的。我不知道这已经足够了。我会尝试这样做。感谢您的帮助。
      • @user2448690:不客气,请考虑学习布局管理器。否则,您可能会创建不灵活的 GUI,在除您的平台之外的所有平台上看起来都很糟糕。
      猜你喜欢
      • 1970-01-01
      • 2016-04-20
      • 2020-01-23
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多