gpt4 book ai didi

java - 如果单击可见 JPopupMenu 外部,则强制选择 JTable 行

转载 作者:行者123 更新时间:2023-11-30 02:45:41 25 4
gpt4 key购买 nike

我已使用 setComponentPopupMenuJPopupMenu 添加到 JTable。问题是,虽然 JPopupMenu 打开/可见,但当我左键单击弹出菜单外部的行时,菜单会关闭,但该行未被选中,因此我必须再次单击它才能突出显示它。有什么办法可以解决这个问题吗?

编辑

我添加了示例代码。

顺便说一句,此行为仅发生在 Windows LaF 中。我刚刚测试过它,看来默认的 Java LaF 允许在 JPopupMenu 打开时左键单击行选择。

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class TableSTACK {

private static void createAndShowGUI() {

String[] headers = {"Column 1", "Column 2"};

Object[][] data = { {"Row", "1"}, {"Row", "2"},
{"Row", "3"}, {"Row", "4"}, {"Row", "5"},
{"Row", "6"}, {"Row", "7"}, {"Row", "8"}, };

JTable table = new JTable(data, headers);
table.setFillsViewportHeight(true);
table.setPreferredScrollableViewportSize(table.getPreferredSize());

final JMenuItem item1 = new JMenuItem();
item1.setText("Menu Item 1");
final JMenuItem item2 = new JMenuItem();
item2.setText("Menu Item 2");
final JMenuItem item3 = new JMenuItem();
item3.setText("Menu Item 3");

final JPopupMenu popupMenu = new JPopupMenu();
popupMenu.add(item1);
popupMenu.addSeparator();
popupMenu.add(item2);
popupMenu.add(item3);
table.setComponentPopupMenu(popupMenu);

popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// force selection of row upon right-click (it works)
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
}
});
}

@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// force row selection upon exiting popup menu
// does not work; rowAtPoint always returns -1
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(null, new Point(0, 0), table));
//int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
}
});
}

@Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO
}
});


GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;

JScrollPane scrollPane = new JScrollPane(table);

JPanel contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
contentPane.setLayout(new GridBagLayout());
contentPane.add(scrollPane, gbc);

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(contentPane);
frame.pack();
frame.setMinimumSize(new Dimension(500, 400));
frame.setVisible(true);
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
//UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createAndShowGUI();
}
});
}
}

最佳答案

这是 LAF 问题。

当我使用默认的 LAF 时,它适用于我,但当我使用平台 LAF 时,它不起作用,对我来说,该平台是 Windows。

Windows 上的一个潜在解决方案是使用 MouseListener选择线路。请注意,代码已添加到 mouseReleased事件。由于某种原因,该表没有收到 mousePressed事件即使根据 AWTEventListener该表是 mousePressed 的来源事件。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TablePopupListener extends JPanel
{
public TablePopupListener()
{
JTable table = new JTable(10, 5);
add( new JScrollPane( table ) );

JPopupMenu popup = new JPopupMenu();
popup.add( new JMenuItem("Do Something1") );
popup.add( new JMenuItem("Do Something2") );

table.setComponentPopupMenu( popup );

table.addMouseListener( new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
System.out.println("Pressed JTable");
}

public void mouseReleased(MouseEvent e)
{
System.out.println("Released JTable");

int row = table.rowAtPoint( e.getPoint() );

if (row != -1
&& !table.isRowSelected(row))
{
table.setRowSelectionInterval(row, row);
}
}
});
}

private static void createAndShowGUI()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception ex) { System.out.println(ex); }

JFrame frame = new JFrame("TablePopupListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TablePopupListener());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );

Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener()
{
public void eventDispatched(AWTEvent e)
{
String event = null;

switch (e.getID())
{
case MouseEvent.MOUSE_PRESSED: event = "Pressed: " ; break;
case MouseEvent.MOUSE_RELEASED: event = "Released: " ; break;
case MouseEvent.MOUSE_ENTERED: event = "Entered: " ; break;
case MouseEvent.MOUSE_EXITED: event = "Exited: " ; break;
default: event = null; break;
}

if (event != null)
{
System.out.println();
System.out.println(event + e.getSource().getClass());
}
}
}, AWTEvent.MOUSE_EVENT_MASK);
}

public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}

关于java - 如果单击可见 JPopupMenu 外部,则强制选择 JTable 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40273424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com