带有动态 JPopupMenu 的 JTable
JTable with dynamic JPopupMenu
我正在尝试编写一个根据行更改其项目的上下文菜单。问题是我无法更新它。这是一个工作示例:
package jframe.jTable;
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class TestTableRightClick {
JPopupMenu popupMenu;
protected void initUI() {
final JFrame frame = new JFrame(TestTableRightClick.class.getSimpleName());
Vector<String> columns = new Vector<String>(Arrays.asList("Name", "Age"));
Vector<Vector<String>> data = new Vector<Vector<String>>();
for (int i = 0; i < 50; i++) {
Vector<String> row = new Vector<String>();
for (int j = 0; j < columns.size(); j++) {
row.add("Cell " + (i + 1) + "," + (j + 1));
}
data.add(row);
}
JTable table = new JTable(data, columns);
popupMenu = new JPopupMenu();
popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
//int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
//generateTablePopupMenu(rowAtPoint);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
generateTablePopupMenu(rowAtPoint);
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
}
});
}
private void generateTablePopupMenu(int rowAtPoint) {
System.out.println(rowAtPoint);
popupMenu.removeAll();
if ( (rowAtPoint & 1) == 0 ) {
System.out.println("even");
JMenuItem item = new JMenuItem("Even Row");
popupMenu.add(item);}
else {
System.out.println("odd");
//popupMenu = new JPopupMenu();
JMenuItem item = new JMenuItem("Odd Row");
popupMenu.add(item);}
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
});
table.setComponentPopupMenu(popupMenu);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestTableRightClick().initUI();
}
});
}
}
执行代码时,JPopupMenu 为空白并保持空白,即使正确的行被报告回 generateTablePopupMenu,并添加了新的 JMenuItem。我也试过在 .invokelater 之前制作代码 运行 像这样:
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
generateTablePopupMenu(rowAtPoint);
SwingUtilities.invokeLater(new Runnable() {...
但是返回的行整数总是-1。我怎样才能让它工作?为什么这行得通,为什么我的代码不起作用?我在网上搜索了我的问题的答案,但奇怪的是没有找到太多答案。
每当您 add/remove 来自可见容器的组件时,您需要告诉容器您已完成添加组件,以便可以调用布局管理器。
你的逻辑应该是:
private void generateTablePopupMenu(int rowAtPoint)
{
popupMenu.removeAll();
if ( (rowAtPoint & 1) == 0 )
{
JMenuItem item = new JMenuItem("Even Row");
popupMenu.add(item);}
else
{
JMenuItem item = new JMenuItem("Odd Row");
popupMenu.add(item);
}
popupMenu.revalidate();
}
我正在尝试编写一个根据行更改其项目的上下文菜单。问题是我无法更新它。这是一个工作示例:
package jframe.jTable;
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class TestTableRightClick {
JPopupMenu popupMenu;
protected void initUI() {
final JFrame frame = new JFrame(TestTableRightClick.class.getSimpleName());
Vector<String> columns = new Vector<String>(Arrays.asList("Name", "Age"));
Vector<Vector<String>> data = new Vector<Vector<String>>();
for (int i = 0; i < 50; i++) {
Vector<String> row = new Vector<String>();
for (int j = 0; j < columns.size(); j++) {
row.add("Cell " + (i + 1) + "," + (j + 1));
}
data.add(row);
}
JTable table = new JTable(data, columns);
popupMenu = new JPopupMenu();
popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
//int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
//generateTablePopupMenu(rowAtPoint);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
generateTablePopupMenu(rowAtPoint);
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
}
});
}
private void generateTablePopupMenu(int rowAtPoint) {
System.out.println(rowAtPoint);
popupMenu.removeAll();
if ( (rowAtPoint & 1) == 0 ) {
System.out.println("even");
JMenuItem item = new JMenuItem("Even Row");
popupMenu.add(item);}
else {
System.out.println("odd");
//popupMenu = new JPopupMenu();
JMenuItem item = new JMenuItem("Odd Row");
popupMenu.add(item);}
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
});
table.setComponentPopupMenu(popupMenu);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestTableRightClick().initUI();
}
});
}
}
执行代码时,JPopupMenu 为空白并保持空白,即使正确的行被报告回 generateTablePopupMenu,并添加了新的 JMenuItem。我也试过在 .invokelater 之前制作代码 运行 像这样:
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
generateTablePopupMenu(rowAtPoint);
SwingUtilities.invokeLater(new Runnable() {...
但是返回的行整数总是-1。我怎样才能让它工作?为什么这行得通,为什么我的代码不起作用?我在网上搜索了我的问题的答案,但奇怪的是没有找到太多答案。
每当您 add/remove 来自可见容器的组件时,您需要告诉容器您已完成添加组件,以便可以调用布局管理器。
你的逻辑应该是:
private void generateTablePopupMenu(int rowAtPoint)
{
popupMenu.removeAll();
if ( (rowAtPoint & 1) == 0 )
{
JMenuItem item = new JMenuItem("Even Row");
popupMenu.add(item);}
else
{
JMenuItem item = new JMenuItem("Odd Row");
popupMenu.add(item);
}
popupMenu.revalidate();
}