【问题标题】:Different value of components from JPanel when coming through different event types通过不同事件类型时来自 JPanel 的组件的不同值
【发布时间】:2017-10-24 06:01:43
【问题描述】:

有一个面板包含 4 个组件; 1 个 JLabel、1 个 JButton、1 个 JTextField 和 1 个 JPopupMenu
有一种方法“testMethod()”,首先我从面板中获取组件的数量,然后是组件的类型(JButton、JLabel 等)。

现在控制流转到 testMethod() 时会发生两种情况:

  1. 通过JButton点击事件时,面板上显示4个组件,4个组件全部获取后
  2. 通过 JMenuItem 点击事件时,面板上显示 3 个组件(未获取 JPopupMenu),仅显示 3 个组件后(未获取 JPopupMenu)

我不明白是什么导致了这种行为。我在互联网上搜索了很多,还阅读了 JPopupMenu 文档,但没有找到任何相关信息。

以下是代码:
(这是非常大的代码的一部分,所以我在这里只放了显示场景的代码)

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class TestProject extends JFrame {

    JPanel panel;
    private JPanel contentPane;
    private JTextField textField;

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

    /**
     * Create the frame.
     */
    public TestProject() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        panel = new JPanel();
        contentPane.add(panel, BorderLayout.CENTER);

        JLabel lblNewLabel = new JLabel("New label");
        panel.add(lblNewLabel);

        JButton btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                testMethod();
            }
        });
        panel.add(btnNewButton);

        textField = new JTextField();
        panel.add(textField);
        textField.setColumns(10);

        // Creating upper level container
        JPopupMenu editMenu = new JPopupMenu("Edit");

        JMenuItem item1 = new JMenuItem("Item 1");
        item1.setBackground(Color.WHITE);

        JMenuItem item2 = new JMenuItem("Item 2");
        item2.setBackground(Color.WHITE);
        item2.setBackground(Color.WHITE);
        // Setting Copy action listener
        item2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                testMethod();
            }
        });

        // Adding the menu items on the popup menu
        editMenu.add(item1);
        editMenu.add(item2);

        panel.addMouseListener(new MouseAdapter() {
               public void mouseClicked(MouseEvent e) {
                   // Added check to open menu only on left click
                   if (e.getButton() == MouseEvent.BUTTON3)
                       editMenu.show(panel, e.getX(), e.getY());
               }               
            });

        // Adding popup menu to the logAreaPanel
        panel.add(editMenu); 

    }

    void testMethod()
    {
        // Here getting number of components of panel
        // When coming through JButton click event, it shows 4 components on panel and after get all 4 components 
        int items = panel.getComponentCount();
        Component c;

        // Getting all the trees one by one and storing their data into StringBuilder
        for(int loopCounter = 0; loopCounter < items; loopCounter++)
        {
            // here getting different component types
            // When coming through JMenuItem click event, it shows 3 components on panel(not getting JPopupMenu) and after only 3 components(not getting JPopupMenu)
            c = panel.getComponent(loopCounter);
        }
    }
}

任何帮助将不胜感激。 :-)

【问题讨论】:

  • 一旦你显示了你的弹出菜单,你只会得到3个带有按钮或弹出菜单的组件。问题似乎是,一旦您显示弹出菜单,它就不再包含在 jpanel 中。
  • 嗨@matt 感谢您的回复。对我来说看起来也一样,但我想要一些具体的东西,无论我做错了什么还是只是这样。
  • 您不需要将弹出窗口添加到面板中,tutorial 您只需添加鼠标侦听器并执行弹出窗口即可。它似乎以您的方式自动为您处理鼠标侦听器,所以我不知道它是否错误。如果您阅读教程,您会看到弹出窗口有自己的窗口,这就是为什么它会在显示时从其他组件中删除。
  • @matt 感谢您的建议。请把你的评论作为答案,因为它解决了我的问题。
  • 不要使用panel.add(editMenu),而是使用panel.setComponentPopupMenu(editMenu)

标签: java swing jpanel jpopupmenu


【解决方案1】:

您不需要将弹出窗口添加到组件中。首选的方法是只使用

panel.setComponentPopupMenu(editMenu);

根据tutorial,您可以使用 MouseListener。

//panel.add(editMenu); 
panel.addMouseListener(new MouseAdapter(){
    public void mousePressed(MouseEvent e) {
        maybeShowPopup(e);
    }

    public void mouseReleased(MouseEvent e) {
        maybeShowPopup(e);
    }

    private void maybeShowPopup(MouseEvent e) {
        if (e.isPopupTrigger()) {
            editMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    }
});

这样组件计数将始终为三个,因为它永远不会添加到面板中。

【讨论】:

  • 或者,最好使用panel.setComponentPopupMenu(editMenu);,让系统处理
猜你喜欢
  • 2014-04-13
  • 1970-01-01
  • 1970-01-01
  • 2020-02-11
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多