如何通过单击按钮重新绘制 jpanel 并在 2 个面板之间切换

Posted

技术标签:

【中文标题】如何通过单击按钮重新绘制 jpanel 并在 2 个面板之间切换【英文标题】:how to repaint a jpanel with button click and also switch between 2 panels 【发布时间】:2013-10-26 08:04:34 【问题描述】:

我正在尝试通过单击按钮重新绘制面板,但它没有发生。我尝试使用许多方法,如 setEnabled(true)、setVisible(true)、repaint(),但这些方法都不起作用。而且我还想在两个面板之间切换,比如,如果我点击“总投票”按钮,一个面板应该显示,当我点击“部门投票”时,另一个面板应该显示在同一个地方。

请帮忙。提前致谢。

我在这里提供代码:

public class RSummary extends JFrame implements ActionListener

    JFrame rframe = new JFrame();
    JPanel panel1, panel2, panel3, panel4, panel5;
    JTable table;
    JScrollPane scroll;
    JSplitPane splitPane;
    JButton butx;

   public RSummary()
   

    rframe.setSize(550,300);
    rframe.setLocationRelativeTo(null);

    setSize(550,300);
        rframe.setTitle("Summary Report");

        /* Total Vote  & Department wise vote buttons */
           panel1= new JPanel();
          JButton but1 = new JButton("TOTAL VOTE");
          JButton but2 = new JButton("DEPTARTMENT WISE VOTE");
          but1.addActionListener(this);
          panel1.add(but1);
          panel1.add(but2);

          /* Report contents according to button */
          panel2 = new JPanel();
         String[] columnNames = "Name", "Department","Phno","LUID","Select";
        DefaultTableModel model1 = new DefaultTableModel();
        model1.setColumnIdentifiers(columnNames);
        table = new JTable();
        table.setModel(model1); 
        table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        table.setFillsViewportHeight(true);
        scroll = new JScrollPane(table);
        panel2.add(scroll);
        panel2.setVisible(false);


        /* close button */
        panel3 = new JPanel();
        JButton but4= new JButton("CLOSE");
        but4.addActionListener(this);
        panel3.add(but4);


        /* Page heading */
        panel4 = new JPanel();
        JLabel lab =new JLabel("VOTE SUMMARY REPORT");
        panel4.add(lab);


        /* dummy panel */
        panel5 = new JPanel();
        JButton butx = new JButton("Hello butx");
        panel5.add(butx);


    splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel1, panel2);
    rframe.add(splitPane);
    rframe.add(panel3,BorderLayout.SOUTH);
    rframe.add(panel4,BorderLayout.NORTH);

    rframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    rframe.setVisible(true);

  

    public void actionPerformed(ActionEvent ae)
     
String action=ae.getActionCommand();

if(action == "CLOSE")

    rframe.setVisible(false);

if(action == "TOTAL VOTE")

    panel2.setVisible(true);  //this code is not working, i want the solution here. 


    
   public static void main(String args[]) throws ClassNotFoundException, SQLException
   
        new RSummary();

    
    

【问题讨论】:

“” 您现在想在这里回答哪两个问题?他们是 2 个 SSCCEs 的 2 个问题的候选人。 【参考方案1】:

第一个问题是您正在比较 String 值的对象引用,而不是内容...

if(action == "TOTAL VOTE")

由于Strings 是由 Java 管理的,它们不太可能永远相等。

String 在 Java 中的比较是使用 String#equals 完成的

if ("TOTAL VOTE".equals(action)) 

您的第二个问题可能与 setVisible 可能不会使容器层次结构无效这一事实有关,这会告诉布局框架需要更新容器。

您有两个解决方案,第一个是在父容器上调用 revalidate,第二个更好的是使用 CardLayout,它专为您正在尝试做的事情而设计。 .

查看How to use Card Layout了解更多详情

运行代码后更新

你有一系列复杂的问题......

你从来没有设置任何按钮的动作命令,所以当actionPerformed事件被引发时,action实际上是null RSummary 扩展自 JFrame,但您创建了第二个 JFrame,名为 rframe。这非常令人困惑,如果您没有处理正确的框架,可能会导致更多问题。

首先设置按钮的actionCommand 属性...

JButton but1 = new JButton("TOTAL VOTE");
but1.setActionCommand("TOTAL VOTE");

然后从RSummary 中删除extends JFrame,因为它只会增加混乱并没有任何好处

将框架设置为不可见不会“关闭”它。而是使用JFrame#dispose

最后,让一个组件在它是拆分窗格的一部分时可见,不会调整拆分分隔线的大小。完成更正后,您需要手动移动分隔线。

您可以考虑在拆分窗格中放置一个空面板并使用CardLayout,将其他组件添加到其中,使用CardLayout 切换它们

使用修改后的代码更新

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class RSummary extends JFrame implements ActionListener 

    JFrame rframe = new JFrame();
    JPanel panel1, panel2, panel3, panel4, panel5;
    JTable table;
    JScrollPane scroll;
    JSplitPane splitPane;
    JButton butx;

    public RSummary() 

        rframe.setSize(550, 300);
        rframe.setLocationRelativeTo(null);

        setSize(550, 300);
        rframe.setTitle("Summary Report");

        /* Total Vote  & Department wise vote buttons */
        panel1 = new JPanel();
        JButton but1 = new JButton("TOTAL VOTE");
        but1.setActionCommand("TOTAL VOTE");
        JButton but2 = new JButton("DEPTARTMENT WISE VOTE");
        but1.addActionListener(this);
        panel1.add(but1);
        panel1.add(but2);

        /* Report contents according to button */
        panel2 = new JPanel();
        String[] columnNames = "Name", "Department", "Phno", "LUID", "Select";
        DefaultTableModel model1 = new DefaultTableModel();
        model1.setColumnIdentifiers(columnNames);
        table = new JTable();
        table.setModel(model1);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        table.setFillsViewportHeight(true);
        scroll = new JScrollPane(table);
        panel2.add(scroll);
        panel2.setVisible(false);


        /* close button */
        panel3 = new JPanel();
        JButton but4 = new JButton("CLOSE");
        but4.addActionListener(this);
        panel3.add(but4);


        /* Page heading */
        panel4 = new JPanel();
        JLabel lab = new JLabel("VOTE SUMMARY REPORT");
        panel4.add(lab);


        /* dummy panel */
        panel5 = new JPanel();
        JButton butx = new JButton("Hello butx");
        panel5.add(butx);

        splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel1, panel2);
        rframe.add(splitPane);
        rframe.add(panel3, BorderLayout.SOUTH);
        rframe.add(panel4, BorderLayout.NORTH);

        rframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        rframe.setVisible(true);

    

    public void actionPerformed(ActionEvent ae) 
        String action = ae.getActionCommand();

        if ("CLOSE".equals(action)) 
            rframe.dispose();
        
        if ("TOTAL VOTE".equals(action)) 
            panel2.setVisible(true);  //this code is not working, i want the solution here. 
            panel2.getParent().revalidate();
        

    

    public static void main(String args[]) throws ClassNotFoundException, SQLException 
        new RSummary();

    


【讨论】:

没有效果,我也试过了。如果是这种情况,那么我的其他按钮应该不起作用,但其他按钮工作正常。 我也尝试了“if ("TOTAL VOTE".equals(action))" 语句,但它不起作用 @user2909960 检查更新,我能够通过这些更改运行它... 我对这个问题进行了大量研究,甚至是卡片布局。但我越来越困惑。我实际上在一个窗口中有很多东西,我有一个页面标题,然后我有一个关闭按钮,然后我需要两个按钮和一个空面板,在这些按钮单击后将可见。请您发布您已编辑的更新代码。 当我点击总票数时,面板可见,但拆分窗格不起作用。我必须手动向上移动拆分窗格才能看到内容。【参考方案2】:

要切换面板,您可以:

rframe.remove (panelToRemove);
rframe.add(panelToShow);

这是您问题的答案还是您为什么要重绘?

地理搜索

更新: 总结一下: MadProgrammer 是对的,您必须将 if(action == "TOTAL VOTE") 替换为 if(action.equals("TOTAL VOTE"))(CLOSE 相同)

你必须添加一个actionCommand:

JButton but1 = new JButton("TOTAL VOTE");
but1.addActionListener(this);
but1.setActionCommand("TOTAL VOTE");

更换面板:

if (action.equals("TOTAL VOTE")) 
    tryrframe.remove(panel1;)catch(Exception e)//clear window, maybe there is a method
    tryrframe.remove(panel2;)catch(Exception e)
    tryrframe.remove(panel3;)catch(Exception e)
    rframe.add(panel2);//the panel you want to show

当然,您必须获得对actionPerformed(ActionEvent ae) 的面板的引用。

【讨论】:

当框架加载时,不应该有任何东西,点击按钮面板后应该可以看到。就我而言,有两个按钮,当我单击第一个按钮时,应该显示一个面板,当我单击另一个按钮时,它应该切换到另一个面板 按钮 1:尝试 rframe.remove (panel1);catch (Exception e) try rframe.remove (panel3);catch (Exception e) rframe.add (panel2 ); //对于按钮2,在代码中交换panel2和panel3这个词 M 没有得到清晰的图片,如果你有这段代码,那将非常有帮助。

以上是关于如何通过单击按钮重新绘制 jpanel 并在 2 个面板之间切换的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中单击按钮在 JPanel 中绘制一条线

Java JPanel repaint() 问题?

如何通过单击 JButton 添加 JPanel?

事件发生后如何重新绘制JPanel

使用 CardLayout 单击按钮在 jpanels 之间切换 [重复]

通过按JButton在随机JPanel上绘制圆圈