Below code create a simple JFrame which including one JTable with JPopupMenu. Right Clicks select the clicked row and show the popup.
Problem Is:
When user Maximize the JFrame to screen and right click to last 1-2-3-4-5 or 6th row, Popup appear in wrong location and select wrong row because of popup height correspond to screen height.
How can i achieve this?
MCVE;
package popuptestapp;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.MouseInfo;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
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;
import javax.swing.table.DefaultTableModel;
public class PopupTestApp {
public static boolean RIGHT_TO_LEFT = false;
public static void addComponentsToPane(Container pane) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(
java.awt.ComponentOrientation.RIGHT_TO_LEFT);
}
JScrollPane jScrollPane = new JScrollPane();
JTable table = new JTable();
table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{"", "", "", "", "", "", "", ""}
},
new String [] {
"Column1", "Column2", "Column3", "Column4", "Column5", "Column6", "Column7", "Column8"
}
) {
boolean[] canEdit = new boolean [] {
false, false, false, false, false, false, false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
DefaultTableModel model1 = (DefaultTableModel) table.getModel();
model1.setRowCount(0);
//Fill the table with rows
for (Integer i = 0; i<=250; i++){
model1.addRow(new String[]{"", "", "", "", "", "", "", ""});
}
jScrollPane.setViewportView(table);
pane.add(jScrollPane, BorderLayout.PAGE_END);
//creating JPopupMenu
JPopupMenu popupForTable = new JPopupMenu();
JMenuItem menuItem1;
JMenuItem menuItem2;
JMenuItem menuItem3;
JMenuItem menuItem4;
JMenuItem menuItem5;
JMenuItem menuItem6;
JMenuItem menuItem7;
JMenuItem menuItem8;
JMenuItem menuItem9;
JMenuItem menuItem10;
popupForTable.add(menuItem1 = new JMenuItem ("menuItem1"));
popupForTable.add(menuItem2 = new JMenuItem ("menuItem2"));
popupForTable.add(menuItem3 = new JMenuItem ("menuItem3"));
popupForTable.add(menuItem4 = new JMenuItem ("menuItem4"));
popupForTable.add(menuItem5 = new JMenuItem ("menuItem5"));
popupForTable.add(menuItem6 = new JMenuItem ("menuItem6"));
popupForTable.add(menuItem7 = new JMenuItem ("menuItem7"));
popupForTable.add(menuItem8 = new JMenuItem ("menuItem8"));
popupForTable.add(menuItem9 = new JMenuItem ("menuItem9"));
popupForTable.add(menuItem10 = new JMenuItem ("menuItem10"));
popupForTable.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Point mousePoint = new Point();
mousePoint = MouseInfo.getPointerInfo().getLocation();
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupForTable, new Point(0, 0), table));
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
}
});
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
});
table.setComponentPopupMenu(popupForTable);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("BorderLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(500, 500));
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Use the content pane's default BorderLayout. No need for
//setLayout(new BorderLayout());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
/* Use an appropriate Look and Feel */
try {
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
/* Turn off metal's use bold fonts */
UIManager.put("swing.boldMetal", Boolean.FALSE);
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
I think this is a pretty good example for how you should use/create jpopupmenu. Link
Take a look at SwingUtilities.convertPoint() doc
So, correct your convertPoint()
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(null, mousePoint, table));
I solve the problem. Firstly thanks to #clamp in this question.
---SOLVED---
I have removed below lines from code;
popupForTable.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Point mousePoint = new Point();
mousePoint = MouseInfo.getPointerInfo().getLocation();
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupForTable, new Point(0, 0), table));
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
}
});
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
});
table.setComponentPopupMenu(popupForTable);
And added this MouseListener to table;
table.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
int r = table.rowAtPoint(e.getPoint());
if (r >= 0 && r < table.getRowCount()) {
table.setRowSelectionInterval(r, r);
} else {
table.clearSelection();
}
int rowindex = table.getSelectedRow();
if (rowindex < 0)
return;
if (e.isPopupTrigger() && e.getComponent() instanceof JTable ) {
JPopupMenu popup = popupForTable;
popup.show(e.getComponent(), e.getX(), e.getY());
table.setRowSelectionInterval(r, r);
}
}
});
Thanks all who interested with this question. Maybe this solution help someones in the future.
Related
I'm trying to bind a shortcut for JTable It's working fine for Alphabets but not for Keys like Insert,Delete,Space etc.
For Ex the below code is working for Ctrl+I or whatever alphabet but If I go for Ctrl+Insert it's not working why is that?
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableModel;
public class NewClass {
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewClass.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(createTable()), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static JTable createTable() {
DefaultTableModel tmodel = new DefaultTableModel(3, 5);
JTable table = new JTable(tmodel);
table.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "Insert");
//Not working for VK_INSERT or VK_DELETE or VK_SPACE
table.getActionMap().put("Insert", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Insert Action");
}
});
return table;
}
}
Update 1
It's not working when using WHEN_IN_FOCUSED_WINDOW but working fine if I go for WHEN_FOCUSED or WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
required WHEN_ANCESTOR_OF_FOCUSED_COMPONENT as corect setting for focus (hidden behind JScrolPanes JViewport)
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
The component contains (or is) the component that has the focus. This input map is commonly used for a composite component — a
component whose implementation depends on child components. For
example, JTables make all their bindings using
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT so that if the user is editing, the
up-arrow key (for example) still changes the selected cell.
then all KeyEvent combinations from OPs question and comments works me correctly in Win7 / Win10, Java7 / Java8, from deleted post by MadProgrammer too ( users_rep > 10k )
AFAIK there is restiction, with numbers of modifiers, if is > 2, then CTRL + ALT + SHIFT + Whatever is possible to catch from AWTEventListener or from very complicated KeyListener
code for simulation in SSCCE /MCVE form
.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableModel;
public class NewClass {
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info
: javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(
NewClass.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(createTable()), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static JTable createTable() {
DefaultTableModel tmodel = new DefaultTableModel(3, 5);
JTable table = new JTable(tmodel);
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.CTRL_MASK), "Insert");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK), "Insert");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), "Insert");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "Insert");
table.getActionMap().put("Insert", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action from JTable");
}
});
return table;
}
}
code made by Rob (camickr), print out the KeyBindings (sorry I haven't a link to his and Darryls code ...)
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.filechooser.*;
public class KeyBindings implements ItemListener {
private static final String PACKAGE = "javax.swing.";
private static final String[] COLUMN_NAMES = {"Action", "When Focused",
"When In Focused Window", "When Ancestor"};
private static String selectedItem;
private JComponent contentPane;
private JMenuBar menuBar;
private JTable table;
private JComboBox comboBox;
private Hashtable<String, DefaultTableModel> models;
public KeyBindings() {
models = new Hashtable<String, DefaultTableModel>();
contentPane = new JPanel(new BorderLayout());
contentPane.add(buildNorthComponent(), BorderLayout.NORTH);
contentPane.add(buildCenterComponent(), BorderLayout.CENTER);
resetComponents();
}
public JComponent getContentPane() {
return contentPane;
}
public JMenuBar getMenuBar() {
if (menuBar == null) {
menuBar = createMenuBar();
}
return menuBar;
}
private JComponent buildNorthComponent() {
comboBox = new JComboBox();
JLabel label = new JLabel("Select Component:");
label.setDisplayedMnemonic('S');
label.setLabelFor(comboBox);
JPanel panel = new JPanel();
panel.setBorder(new EmptyBorder(15, 0, 15, 0));
panel.add(label);
panel.add(comboBox);
return panel;
}
private String checkForUIKey(String key) {
if (key.endsWith("UI") && key.indexOf(".") == -1) {
String componentName = key.substring(0, key.length() - 2);
if (componentName.equals("PopupMenuSeparator")
|| componentName.equals("ToolBarSeparator")
|| componentName.equals("DesktopIcon")) {
return null;
} else {
return componentName;
}
}
return null;
}
private JComponent buildCenterComponent() {
DefaultTableModel model = new DefaultTableModel(COLUMN_NAMES, 0);
table = new JTable(model) {
private static final long serialVersionUID = 1L;
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
table.setAutoCreateColumnsFromModel(false);
table.getColumnModel().getColumn(0).setPreferredWidth(200);
table.getColumnModel().getColumn(1).setPreferredWidth(200);
table.getColumnModel().getColumn(2).setPreferredWidth(200);
table.getColumnModel().getColumn(3).setPreferredWidth(200);
Dimension d = table.getPreferredSize();
d.height = 350;
table.setPreferredScrollableViewportSize(d);
table.getTableHeader().setFocusable(true);
return new JScrollPane(table);
}
public void resetComponents() {
models.clear();
Vector<String> comboBoxItems = new Vector<String>(50);
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
for (Object key : defaults.keySet()) {
String componentName = checkForUIKey(key.toString());
if (componentName != null) {
comboBoxItems.add(componentName);
}
}
Collections.sort(comboBoxItems);
comboBox.removeItemListener(this);
comboBox.setModel(new DefaultComboBoxModel(comboBoxItems));
comboBox.setSelectedIndex(-1);
comboBox.addItemListener(this);
comboBox.requestFocusInWindow();
if (selectedItem != null) {
comboBox.setSelectedItem(selectedItem);
}
}
private JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
menuBar.add(createFileMenu());
menuBar.add(createLAFMenu());
return menuBar;
}
private JMenu createFileMenu() {
JMenu menu = new JMenu("Application");
menu.setMnemonic('A');
menu.addSeparator();
menu.add(new ExitAction());
return menu;
}
private JMenu createLAFMenu() {
ButtonGroup bg = new ButtonGroup();
JMenu menu = new JMenu("Look & Feel");
menu.setMnemonic('L');
String lafId = UIManager.getLookAndFeel().getID();
UIManager.LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels();
for (int i = 0; i < lafInfo.length; i++) {
String laf = lafInfo[i].getClassName();
String name = lafInfo[i].getName();
Action action = new ChangeLookAndFeelAction(laf, name);
JRadioButtonMenuItem mi = new JRadioButtonMenuItem(action);
menu.add(mi);
bg.add(mi);
if (name.equals(lafId)) {
mi.setSelected(true);
}
}
return menu;
}
#Override
public void itemStateChanged(ItemEvent e) {
String componentName = (String) e.getItem();
changeTableModel(getClassName(componentName));
selectedItem = componentName;
}
private String getClassName(String componentName) {
if (componentName.equals("TableHeader")) {
return PACKAGE + "table.JTableHeader";
} else {
return PACKAGE + "J" + componentName;
}
}
private void changeTableModel(String className) {
DefaultTableModel model = models.get(className);
if (model != null) {
table.setModel(model);
return;
}
model = new DefaultTableModel(COLUMN_NAMES, 0);
table.setModel(model);
models.put(className, model);
JComponent component = null;
try {// Hack so I don't have to sign the jar file for usage in Java Webstart
if (className.endsWith("JFileChooser")) {
component = new JFileChooser(new DummyFileSystemView());
} else {
Object o = Class.forName(className).newInstance();
component = (JComponent) o;
}
} catch (Exception e) {
Object[] row = {e.toString(), "", "", ""};
model.addRow(row);
return;
}
ActionMap actionMap = component.getActionMap();
Object[] keys = actionMap.allKeys();
if (keys == null) {
Object[] row = {"No actions found", "", "", ""};
model.addRow(row);
return;
}
for (int i = 0; i < keys.length; i++) {
Object key = keys[i];
if (key instanceof String) {
continue;
} else {
keys[i] = "";
}
}
Arrays.sort(keys);
for (int i = 0; i < keys.length; i++) {
Object key = keys[i];
if (key != "") {
Object[] row = {key, "", "", ""};
model.addRow(row);
}
}
updateModelForInputMap(model, 1,
component.getInputMap(JComponent.WHEN_FOCUSED));
updateModelForInputMap(model, 2,
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW));
updateModelForInputMap(model, 3,
component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT));
}
private void updateModelForInputMap(TableModel model, int column, InputMap inputMap) {
if (inputMap == null) {
return;
}
KeyStroke[] keys = inputMap.allKeys();
if (keys == null) {
return;
}
Hashtable<Object, String> actions = new Hashtable<Object, String>(keys.length);
for (int i = 0; i < keys.length; i++) {
KeyStroke key = keys[i];
Object actionName = inputMap.get(key);
Object value = actions.get(actionName);
if (value == null) {
actions.put(actionName, key.toString().replace("pressed ", ""));
} else {
actions.put(actionName, value + ", " + key.toString().replace("pressed ", ""));
}
}
for (int i = 0; i < model.getRowCount(); i++) {
String o = actions.get(model.getValueAt(i, 0));
if (o != null) {
model.setValueAt(o.toString(), i, column);
}
}
}
class ChangeLookAndFeelAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private String laf;
protected ChangeLookAndFeelAction(String laf, String name) {
this.laf = laf;
putValue(Action.NAME, name);
putValue(Action.SHORT_DESCRIPTION, getValue(Action.NAME));
}
#Override
public void actionPerformed(ActionEvent e) {
try {
JMenuItem mi = (JMenuItem) e.getSource();
JPopupMenu popup = (JPopupMenu) mi.getParent();
JRootPane rootPane = SwingUtilities.getRootPane(popup.getInvoker());
Component c = rootPane.getContentPane().getComponent(0);
rootPane.getContentPane().remove(c);
UIManager.setLookAndFeel(laf);
KeyBindings bindings = new KeyBindings();
rootPane.getContentPane().add(bindings.getContentPane());
SwingUtilities.updateComponentTreeUI(rootPane);
rootPane.requestFocusInWindow();
} catch (Exception ex) {
System.out.println("Failed loading L&F: " + laf);
System.out.println(ex);
}
}
}
class ExitAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public ExitAction() {
putValue(Action.NAME, "Exit");
putValue(Action.SHORT_DESCRIPTION, getValue(Action.NAME));
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_X));
}
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
class DummyFileSystemView extends FileSystemView {
#Override
public File createNewFolder(File containingDir) {
return null;
}
#Override
public File getDefaultDirectory() {
return null;
}
#Override
public File getHomeDirectory() {
return null;
}
}
private static void createAndShowGUI() {
KeyBindings application = new KeyBindings();
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Key Bindings");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(application.getMenuBar());
frame.getContentPane().add(application.getContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
/*try {
SynthLookAndFeel laf = new SynthLookAndFeel();
UIManager.setLookAndFeel(laf);
KeyBindings bindings = new KeyBindings();
} catch (UnsupportedLookAndFeelException ex) {
Logger.getLogger(KeyBindings.class.getName()).log(Level.SEVERE, null, ex);
} */
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}
without selection
Delete Action from JTable
Insert Action from JTable
Space Action from JTable
I Action from JTable
after cell is selected
Delete Action from JTable
Insert Action from JTable
Space Action from JTable
I Action from JTable
from code, for correctness is required (otherwise there is bunch of unfilteres events, but completed for testing purposes) to test for CTRL && Whatever is Pressed insideAWTEventListener
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class NewClass {
private JFrame frame = new JFrame();
private DefaultTableModel tmodel = new DefaultTableModel(3, 5);
private JTable table = new JTable(tmodel);
public NewClass() {
frame.add(new JScrollPane(createTable()), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
if (event instanceof KeyEvent) {
KeyEvent ke = (KeyEvent) event;
Component comp = ke.getComponent();
if (comp instanceof JTable) {
System.out.println(comp);
} else if (comp instanceof JScrollPane) {
System.out.println(comp);
} else if (comp instanceof JViewport) {
System.out.println(comp);
} else if (comp instanceof JFrame) {
System.out.println(comp);
} else {
System.out.println(comp);
}
}
}
}, AWTEvent.KEY_EVENT_MASK);
}
public JTable createTable() {
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, KeyEvent.CTRL_MASK), "Delete");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK), "Insert");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), "Space");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK), "I");
table.getActionMap().put("Delete", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Delete Action from JTable");
}
});
table.getActionMap().put("Insert", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Insert Action from JTable");
}
});
table.getActionMap().put("Space", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Space Action from JTable");
}
});
table.getActionMap().put("I", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("I Action from JTable");
}
});
return table;
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info
: javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException |
javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(
NewClass.class.getName()).log(
java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new NewClass();
}
});
}
}
I have a JPopupMenu that is displayed when a JButton is held down. This menu contains a series of JMenuItems, each associated with an action, that change sometimes. The problem I'm having is that intermitently the JMenuItems aren't being drawn, I simply get a grey JPopupMenu, but the items appear if I move the mouse cursor over them. I thought the problem might be with not properly repainting the components after changes, but testing show the problem keeps happening even when there are no changes to the items. Here is the relevant code:
if (!listChanged) {
myPopupMenu.show(myButton, x, y);
} else {
List<String> menuList = getMenuList();
MyData data = getData();
myPopupMenu.removeAll();
for (int i = 0; i < menuList.size(); i++) {
String name = menuList.get(i);
JMenuItem item = new JMenuItem(new MyMenuAction(this, name,
data, i));
item.addActionListener(this);
myPopupMenu.add(item);
myPopupMenu.validate();
}
myPopupMenu.repaint();
myPopupMenu.show(myButton, x, y);
}
...
private static class MyMenuAction extends AbstractAction {
private MyClass parent;
private int index;
private MyData data;
public MyMenuAction (MyClass parent, String name,
MyData data, int index) {
super(name);
this.parent = parent;
this.index = index;
this.data = data;
}
#Override
public void actionPerformed(ActionEvent e) {
Object[] actionParameters;
try {
actionParameters = data.getParameters(index);
} catch (ImmediateException e1) {
log(e1.getMessage(), "Error");
return;
}
parent.myButtonAction(actionParameters);
}
}
Just to clarify, the actions are working fine and 8 times out of 10 the JPopupMenu and all the JMenuItems are drawn right, but I can't figure out why they don't appear sometimes (regardless of whether the list has changed or not). Any help would be appreciated.
EDIT:
Ok, following Andrew Thompson's recomendation, here is a short complete example. Many of the methods have been striped bare, but the basic is still there. Just click and hold the button "SHOW MENU" to display the JPopupMenu. Since the problem is intermitent, it may be necessary to do it several times until the problem occurs.
package main;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JToolBar;
import javax.swing.UIManager;
public class MyClass implements ActionListener, MouseListener {
boolean listChanged = true;
boolean mousePressed = false;
long clickStart;
JPopupMenu myPopupMenu;
JButton myButton;
JFrame myFrame;
ArrayList<String> list;
public static void main(String[] args) {
MyClass myClass = new MyClass();
myClass.start();
}
private void start() {
myFrame = new JFrame();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
System.out.println(e.getClass().getName() + " " + e.getMessage());
}
startList();
myButton = new JButton("SHOW MENU");
myPopupMenu = new JPopupMenu();
JToolBar toolbar = new JToolBar();
toolbar.add(new JButton("Button1"));
toolbar.add(new JButton("Button2"));
toolbar.add(new JButton("Button3"));
toolbar.add(new JButton("Button4"));
toolbar.add(new JButton("Button5"));
toolbar.add(myButton);
myButton.addMouseListener(this);
toolbar.setBorder(BorderFactory.createEtchedBorder(1));
JPanel emptyPanel = new JPanel();
myFrame.add(toolbar, BorderLayout.PAGE_START);
myFrame.add(emptyPanel, BorderLayout.CENTER);
myFrame.pack();
myFrame.setExtendedState(myFrame.getExtendedState()
| JFrame.MAXIMIZED_BOTH);
myFrame.setVisible(true);
}
public void showMenu() {
if (!listChanged) {
myPopupMenu.show(myButton, 0, myButton.getHeight());
} else {
listChanged = false;
List<String> menuList = getMenuList();
MyData data = getData();
myPopupMenu.removeAll();
for (int i = 0; i < menuList.size(); i++) {
String name = menuList.get(i);
JMenuItem item = new JMenuItem(new MyMenuAction(this, name,
data, i));
item.addActionListener(this);
myPopupMenu.add(item);
myPopupMenu.validate();
}
myPopupMenu.repaint();
myPopupMenu.show(myButton, 0, myButton.getHeight());
}
}
private void startList() {
list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
list.add("Item 3");
list.add("Item 4");
list.add("Item 5");
}
private List<String> getMenuList() {
return list;
}
public void myButtonAction() {
Object[] defaultParameters = getDefaultParameters();
myButtonAction(defaultParameters);
}
private Object[] getDefaultParameters() {
// Placeholder
return null;
}
public void myButtonAction(Object[] actionParameters) {
// Placeholder
}
private MyData getData() {
// Placeholder
return new MyData();
}
private void changeList(List<String> newList) {
list.clear();
list.addAll(newList);
listChanged = true;
}
#Override
public void actionPerformed(ActionEvent e) {
// Placeholder
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
if (e.getSource() == myButton) {
mousePressed = true;
clickStart = System.currentTimeMillis();
new Thread(new Runnable() {
#Override
public void run() {
synchronized (this) {
while (mousePressed)
try {
this.wait(10);
if (System.currentTimeMillis() - clickStart > 300) {
MyClass.this.showMenu();
return;
}
} catch (InterruptedException e1) {
break;
}
MyClass.this.myButtonAction();
}
}
}).start();
}
}
#Override
public void mouseReleased(MouseEvent e) {
mousePressed = false;
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
private static class MyData {
public Object[] getParameters(int index) {
// Placeholder
return null;
}
}
private static class MyMenuAction extends AbstractAction {
private MyClass parent;
private int index;
private MyData data;
public MyMenuAction(MyClass parent, String name, MyData data, int index) {
super(name);
this.parent = parent;
this.index = index;
this.data = data;
}
#Override
public void actionPerformed(ActionEvent e) {
Object[] actionParameters;
try {
actionParameters = data.getParameters(index);
} catch (Exception e1) {
System.out.println(e1.getMessage());
return;
}
parent.myButtonAction(actionParameters);
}
}
}
I have a JPopupMenu that is displayed when a JButton is held down.
First of all I have a problem with a UI like that. The standard is to show a popup when you right click (in windows). Follow known standards. Read the section from the Swing tutorial on Bringing Up a Popup Menu for more information and working examples.
Secondly, I can't reproduce the problem (no matter how long I try). Random problems are usually caused by the GUI not being updated on the EDT. So don't use a Thread.
Instead use a Swing Timer.
Set the Timer to fire after 200ms at which time you display the menu. Code executed from the Timer IS invoked on the EDT. So you would restart() the Timer in mousePressed. and stop() the Timer in mouseReleased.
I am building a java app and I want to change the theme(look and feel) of application at runtime with these radio buttons. I do not know how to do this!
Thanks in advance!
You can do that by calling SwingUtilities.updateTreeComponentUI(frame) and passing container component. Be aware that it won't be efficient always. So something like this:
public static void changeLaf(JFrame frame) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(frame);
}
This method changes current LaF to systems.
EDIT:
Changing LaF via JRadioMenuItem demo:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class LafDemo {
public static void changeLaf(JFrame frame, String laf) {
if (laf.equals("metal")) {
try {
UIManager.setLookAndFeel(UIManager
.getCrossPlatformLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
if (laf.equals("nimbus")) {
try {
UIManager
.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
if (laf.equals("system")) {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
SwingUtilities.updateComponentTreeUI(frame);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton btnDemo = new JButton("JButton");
JSpinner spnDemo = new JSpinner();
JComboBox<String> cmbDemo = new JComboBox<String>();
cmbDemo.addItem("One");
cmbDemo.addItem("Two");
cmbDemo.addItem("Three");
JMenuBar mBar = new JMenuBar();
frame.setJMenuBar(mBar);
JMenu mnuLaf = new JMenu("Look and feel");
JRadioButtonMenuItem mniNimbus = new JRadioButtonMenuItem(
"Nimbus");
JRadioButtonMenuItem mniMetal = new JRadioButtonMenuItem(
"Metal");
JRadioButtonMenuItem mniSystem = new JRadioButtonMenuItem(
"Systems");
ButtonGroup btnGroup = new ButtonGroup();
btnGroup.add(mniNimbus);
btnGroup.add(mniMetal);
btnGroup.add(mniSystem);
mBar.add(mnuLaf);
mnuLaf.add(mniNimbus);
mnuLaf.add(mniMetal);
mnuLaf.add(mniSystem);
mniNimbus.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "nimbus");
}
});
mniMetal.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "metal");
}
});
mniSystem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
changeLaf(frame, "system");
}
});
DefaultTableModel model = new DefaultTableModel(
new Object[][] {}, new String[] { "First", "Second" });
model.addRow(new Object[] { "Some text", "Another text" });
JTable table = new JTable(model);
panel.add(btnDemo);
panel.add(spnDemo);
panel.add(cmbDemo);
frame.add(panel, BorderLayout.NORTH);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
You simply need to use the UIManager.LookAndFeelInfo[] to store the available LookAndFeel, then use UIManager.setLookAndFeel(LookAndFeelClassName) to set and after this do call SwingUtilities.updateComponentTreeUI(frameReference)
EDIT :
Do call pack on JFrame/JWindow/JDialog(parent container) at the end, as very much specified by the Swing Lord #AndrewThompson.
Please have a look at this small example :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LookAndFeelDemo {
private JFrame frame;
private JButton button;
private int counter;
private Timer timer;
private JLabel lafNameLabel;
private UIManager.LookAndFeelInfo[] lafs;
public LookAndFeelDemo() {
lafs = UIManager.getInstalledLookAndFeels();
counter = 0;
}
private ActionListener eventActions = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == timer) {
counter %= lafs.length;
try {
UIManager.setLookAndFeel(lafs[counter].getClassName());
} catch(Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
lafNameLabel.setText(lafs[counter++].getName());
frame.pack();
} else if (ae.getSource() == button) {
if (timer.isRunning()) {
timer.stop();
button.setText("Start");
} else {
timer.start();
button.setText("Stop");
}
}
}
};
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
lafNameLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
button = new JButton("Stop");
button.addActionListener(eventActions);
contentPane.add(lafNameLabel);
contentPane.add(button);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
timer.stop();
}
});
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, eventActions);
timer.start();
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new LookAndFeelDemo().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
EDIT 2 :
Updating the code example to include adding LookAndFeels from JRadioButtonMenuItem on the fly. Though please, be advised, it would be much better if you use Action instead of an ActionListener, I used it only to incorporate the changes in the previous code :-)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LookAndFeelDemo {
private JFrame frame;
private JButton button;
private int counter;
private Timer timer;
private JLabel lafNameLabel;
private ButtonGroup bg;
private JRadioButtonMenuItem[] radioItems;
private UIManager.LookAndFeelInfo[] lafs;
public LookAndFeelDemo() {
lafs = UIManager.getInstalledLookAndFeels();
counter = 0;
}
private ActionListener eventActions = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == timer) {
counter %= lafs.length;
try {
UIManager.setLookAndFeel(lafs[counter].getClassName());
} catch(Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
lafNameLabel.setText(lafs[counter++].getName());
frame.pack();
} else if (ae.getSource() == button) {
if (timer.isRunning()) {
timer.stop();
button.setText("Start");
} else {
timer.start();
button.setText("Stop");
}
} else if (ae.getSource() instanceof JRadioButtonMenuItem) {
JRadioButtonMenuItem radioItem = (JRadioButtonMenuItem) ae.getSource();
String lafName = radioItem.getActionCommand();
System.out.println("LAF Name : " + lafName);
for (int i = 0; i < radioItems.length; i++) {
if (lafName.equals(radioItems[i].getActionCommand())) {
setApplicationLookAndFeel(lafs[i].getClassName());
}
}
}
}
private void setApplicationLookAndFeel(String className) {
try {
UIManager.setLookAndFeel(className);
} catch (Exception e) {e.printStackTrace();}
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
}
};
private void displayGUI() {
frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
lafNameLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
button = new JButton("Start");
button.addActionListener(eventActions);
contentPane.add(lafNameLabel);
contentPane.add(button);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
timer.stop();
}
});
frame.setJMenuBar(getMenuBar());
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, eventActions);
}
private JMenuBar getMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu lookAndFeelMenu = new JMenu("Look And Feels");
bg = new ButtonGroup();
radioItems = new JRadioButtonMenuItem[lafs.length];
for (int i = 0; i < radioItems.length; i++) {
radioItems[i] = new JRadioButtonMenuItem(lafs[i].getName());
radioItems[i].addActionListener(eventActions);
bg.add(radioItems[i]);
lookAndFeelMenu.add(radioItems[i]);
}
menuBar.add(lookAndFeelMenu);
return menuBar;
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new LookAndFeelDemo().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
Well, considering Nimbus is currently selected, I am going to assume that you want to change the LAF to Nimbus? If so, you will need to do this:
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
If you want to see all of the LAFs that are currently installed, you could use UIManager.getInstalledLookAndFeels();. For more information, consider reading this
Here's mine:
You should call this method when a Action event occurs when the user clicks on a JMenuItem or something else of your choice.
private void changeLookAndFeel() {
final LookAndFeelInfo[] list = UIManager.getInstalledLookAndFeels();
final List<String> lookAndFeelsDisplay = new ArrayList<>();
final List<String> lookAndFeelsRealNames = new ArrayList<>();
for (LookAndFeelInfo each : list) {
lookAndFeelsDisplay.add(each.getName());
lookAndFeelsRealNames.add(each.getClassName());
}
if (lookAndFeelsDisplay.size() != lookAndFeelsRealNames.size()) {
throw new InternalError();
}
String changeSpeed = (String) JOptionPane.showInputDialog(this, "Choose Look and Feel Here\n(these are all available on your system):", "Choose Look And Feel", JOptionPane.QUESTION_MESSAGE, null, lookAndFeelsDisplay.toArray(), null);
boolean update = false;
if (changeSpeed != null && changeSpeed.length() > 0) {
for (int a = 0; a < lookAndFeelsDisplay.size(); a++) {
if (changeSpeed.equals(lookAndFeelsDisplay.get(a))) {
try {
UIManager.setLookAndFeel(lookAndFeelsRealNames.get(a)); //re update with correct class name String
this.whichLookAndFeel = changeSpeed;
update = true;
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
err.println(ex);
ex.printStackTrace();
Logger.getLogger(Starfighter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
if (update) {
int width = 800;
int height = 625;
if (UIManager.getLookAndFeel().getName().equals("CDE/Motif")) {
height += 12;
}
this.setSize(width, height);
this.menuBar.updateUI();
this.menuBar = new JMenuBar();
menuBar.updateUI();
this.setJMenuBar(menuBar);
}
}
I want to implement dragging and dropping of files from a directory such as someones hard drive but can't figure out how to do it. I've read the java api but it talks of color pickers and dragging and dropping between lists but how to drag files from a computers file system and drop into my application. I tried writing the transferhandler class and a mouse event for when the drag starts but nothing seems to work. Now I'm back to just having my JFileChooser set so drag has been enabled but how to drop?
Any info or point in the right direction greatly appreciated.
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
public class FileChooserDemo
extends JPanel
implements ActionListener
{
JLabel selectedFileLabel;
JList selectedFilesList;
JLabel returnCodeLabel;
public FileChooserDemo()
{
super();
createContent();
}
void initFrameContent()
{
JPanel closePanel = new JPanel();
add(closePanel, BorderLayout.SOUTH);
}
private void createContent()
{
setLayout(new BorderLayout());
JPanel NorthPanel = new JPanel();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem quit = new JMenuItem("Quit");
menuBar.add(menu);
menu.add(quit);
NorthPanel.add(menu,BorderLayout.NORTH);
JPanel buttonPanel = new JPanel(new GridLayout(7,1 ));
JButton openButton = new JButton("Open...");
openButton.setActionCommand("OPEN");
openButton.addActionListener(this);
buttonPanel.add(openButton);
JButton saveButton = new JButton("Save...");
saveButton.setActionCommand("SAVE");
saveButton.addActionListener(this);
buttonPanel.add(saveButton);
JButton delete = new JButton("Delete");
delete.addActionListener(this);
delete.setActionCommand("DELETE");
buttonPanel.add(delete);
add(buttonPanel, BorderLayout.WEST);
// create a panel to display the selected file(s) and the return code
JPanel displayPanel = new JPanel(new BorderLayout());
selectedFileLabel = new JLabel("-");
selectedFileLabel.setBorder(BorderFactory.createTitledBorder
("Selected File/Directory "));
displayPanel.add(selectedFileLabel, BorderLayout.NORTH);
selectedFilesList = new JList();
JScrollPane sp = new JScrollPane(selectedFilesList);
sp.setBorder(BorderFactory.createTitledBorder("Selected Files "));
MouseListener listener = new MouseAdapter()
{
public void mousePressed(MouseEvent me)
{
JComponent comp = (JComponent) me.getSource();
TransferHandler handler = comp.getTransferHandler();
handler.exportAsDrag(comp, me, TransferHandler.MOVE);
}
};
selectedFilesList.addMouseListener(listener);
displayPanel.add(sp);
returnCodeLabel = new JLabel("");
returnCodeLabel.setBorder(BorderFactory.createTitledBorder("Return Code"));
displayPanel.add(returnCodeLabel, BorderLayout.SOUTH);
add(displayPanel);
}
public void actionPerformed(ActionEvent e)
{
int option = 0;
File selectedFile = null;
File[] selectedFiles = new File[0];
if (e.getActionCommand().equals("CLOSE"))
{
System.exit(0);
}
else if (e.getActionCommand().equals("OPEN"))
{
JFileChooser chooser = new JFileChooser();
chooser.setDragEnabled(true);
chooser.setMultiSelectionEnabled(true);
option = chooser.showOpenDialog(this);
selectedFiles = chooser.getSelectedFiles();
}
else if (e.getActionCommand().equals("SAVE"))
{
JFileChooser chooser = new JFileChooser();
option = chooser.showSaveDialog(this);
selectedFiles = chooser.getSelectedFiles();
}
// display the selection and return code
if (selectedFile != null)
selectedFileLabel.setText(selectedFile.toString());
else
selectedFileLabel.setText("null");
DefaultListModel listModel = new DefaultListModel();
for (int i =0; i < selectedFiles.length; i++)
listModel.addElement(selectedFiles[i]);
selectedFilesList.setModel(listModel);
returnCodeLabel.setText(Integer.toString(option));
}
public static void main(String[] args)
{
SwingUtilities.invokeLater
(new Runnable()
{
public void run()
{
FileChooserDemo app = new FileChooserDemo();
app.initFrameContent();
JFrame frame = new JFrame("LoquetUP");
frame.getContentPane().add(app);
frame.setDefaultCloseOperation(3);
frame.setSize(600,400);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
//frame.pack();
frame.setVisible(true);
}
});
}
}
This is my take on the idea. I've used the "traditional" drag and drop API in this example. It has some extra "paint" tweaks just to show off what you might be able to do.
This example doesn't scan folders dropped onto it, so any folder will only register as a single file, but I'm sure you can work it out
public class TestDragNDropFiles {
public static void main(String[] args) {
new TestDragNDropFiles();
}
public TestDragNDropFiles() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DropPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DropPane extends JPanel {
private DropTarget dropTarget;
private DropTargetHandler dropTargetHandler;
private Point dragPoint;
private boolean dragOver = false;
private BufferedImage target;
private JLabel message;
public DropPane() {
try {
target = ImageIO.read(new File("target.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
message = new JLabel();
message.setFont(message.getFont().deriveFont(Font.BOLD, 24));
add(message);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected DropTarget getMyDropTarget() {
if (dropTarget == null) {
dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, null);
}
return dropTarget;
}
protected DropTargetHandler getDropTargetHandler() {
if (dropTargetHandler == null) {
dropTargetHandler = new DropTargetHandler();
}
return dropTargetHandler;
}
#Override
public void addNotify() {
super.addNotify();
try {
getMyDropTarget().addDropTargetListener(getDropTargetHandler());
} catch (TooManyListenersException ex) {
ex.printStackTrace();
}
}
#Override
public void removeNotify() {
super.removeNotify();
getMyDropTarget().removeDropTargetListener(getDropTargetHandler());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (dragOver) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(0, 255, 0, 64));
g2d.fill(new Rectangle(getWidth(), getHeight()));
if (dragPoint != null && target != null) {
int x = dragPoint.x - 12;
int y = dragPoint.y - 12;
g2d.drawImage(target, x, y, this);
}
g2d.dispose();
}
}
protected void importFiles(final List files) {
Runnable run = new Runnable() {
#Override
public void run() {
message.setText("You dropped " + files.size() + " files");
}
};
SwingUtilities.invokeLater(run);
}
protected class DropTargetHandler implements DropTargetListener {
protected void processDrag(DropTargetDragEvent dtde) {
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrag(DnDConstants.ACTION_COPY);
} else {
dtde.rejectDrag();
}
}
#Override
public void dragEnter(DropTargetDragEvent dtde) {
processDrag(dtde);
SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
repaint();
}
#Override
public void dragOver(DropTargetDragEvent dtde) {
processDrag(dtde);
SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
repaint();
}
#Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
#Override
public void dragExit(DropTargetEvent dte) {
SwingUtilities.invokeLater(new DragUpdate(false, null));
repaint();
}
#Override
public void drop(DropTargetDropEvent dtde) {
SwingUtilities.invokeLater(new DragUpdate(false, null));
Transferable transferable = dtde.getTransferable();
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrop(dtde.getDropAction());
try {
List transferData = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor);
if (transferData != null && transferData.size() > 0) {
importFiles(transferData);
dtde.dropComplete(true);
}
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
dtde.rejectDrop();
}
}
}
public class DragUpdate implements Runnable {
private boolean dragOver;
private Point dragPoint;
public DragUpdate(boolean dragOver, Point dragPoint) {
this.dragOver = dragOver;
this.dragPoint = dragPoint;
}
#Override
public void run() {
DropPane.this.dragOver = dragOver;
DropPane.this.dragPoint = dragPoint;
DropPane.this.repaint();
}
}
}
}
You need to experiment with Drag & Drop and see exactly what flavors are available when you try to drag files. If you do this in your custom TransferHandler you'll be pleasantly surprised one Flavor is the DataFlavor.javaFileListFlavor, which indicates that the item can be used simply as a List. Try it and you'll see that it works!
Note on review of your posted code, I don't see any code for your attempt at using a TransferHandler, so it is hard to say what you could be doing wrong here.
Edit 1
You seem to be trying to use a MouseListener for your drag and drop, and I'm not familiar with this usage. Can you show a reference to a tutorial that tells you to do this?
Edit 2
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class FileDragDemo extends JPanel {
private JList list = new JList();
public FileDragDemo() {
list.setDragEnabled(true);
list.setTransferHandler(new FileListTransferHandler(list));
add(new JScrollPane(list));
}
private static void createAndShowGui() {
FileDragDemo mainPanel = new FileDragDemo();
JFrame frame = new JFrame("FileDragDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class FileListTransferHandler extends TransferHandler {
private JList list;
public FileListTransferHandler(JList list) {
this.list = list;
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
public boolean canImport(TransferSupport ts) {
return ts.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
}
public boolean importData(TransferSupport ts) {
try {
#SuppressWarnings("rawtypes")
List data = (List) ts.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
if (data.size() < 1) {
return false;
}
DefaultListModel listModel = new DefaultListModel();
for (Object item : data) {
File file = (File) item;
listModel.addElement(file);
}
list.setModel(listModel);
return true;
} catch (UnsupportedFlavorException e) {
return false;
} catch (IOException e) {
return false;
}
}
}
I want to add JComboBox inside a JTable (3,3) on column 1. But in the column 1 , each row will have its own set of ComboBox element.
When I tried to use
table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(comboBox_Custom));
Each row is being set to same set of ComboBox Values.
But I want each row ComboBox has different items.
example on java2s.com looks like as works and correctly, then for example (I harcoded JComboBoxes for quick example, and add/change for todays Swing)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.table.*;
public class EachRowEditorExample extends JFrame {
private static final long serialVersionUID = 1L;
public EachRowEditorExample() {
super("EachRow Editor Example");
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
System.out.println(info.getName());
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (UnsupportedLookAndFeelException e) {
// handle exception
} catch (ClassNotFoundException e) {
// handle exception
} catch (InstantiationException e) {
// handle exception
} catch (IllegalAccessException e) {
// handle exception
}
DefaultTableModel dm = new DefaultTableModel();
dm.setDataVector(new Object[][]{{"Name", "MyName"}, {"Gender", "Male"}, {"Color", "Fruit"}}, new Object[]{"Column1", "Column2"});
JTable table = new JTable(dm);
table.setRowHeight(20);
JComboBox comboBox = new JComboBox();
comboBox.addItem("Male");
comboBox.addItem("Female");
comboBox.addComponentListener(new ComponentAdapter() {
#Override
public void componentShown(ComponentEvent e) {
final JComponent c = (JComponent) e.getSource();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
c.requestFocus();
System.out.println(c);
if (c instanceof JComboBox) {
System.out.println("a");
}
}
});
}
});
JComboBox comboBox1 = new JComboBox();
comboBox1.addItem("Name");
comboBox1.addItem("MyName");
comboBox1.addComponentListener(new ComponentAdapter() {
#Override
public void componentShown(ComponentEvent e) {
final JComponent c = (JComponent) e.getSource();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
c.requestFocus();
System.out.println(c);
if (c instanceof JComboBox) {
System.out.println("a");
}
}
});
}
});
JComboBox comboBox2 = new JComboBox();
comboBox2.addItem("Banana");
comboBox2.addItem("Apple");
comboBox2.addComponentListener(new ComponentAdapter() {
#Override
public void componentShown(ComponentEvent e) {
final JComponent c = (JComponent) e.getSource();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
c.requestFocus();
System.out.println(c);
if (c instanceof JComboBox) {
System.out.println("a");
}
}
});
}
});
EachRowEditor rowEditor = new EachRowEditor(table);
rowEditor.setEditorAt(0, new DefaultCellEditor(comboBox1));
rowEditor.setEditorAt(1, new DefaultCellEditor(comboBox));
rowEditor.setEditorAt(2, new DefaultCellEditor(comboBox2));
table.getColumn("Column2").setCellEditor(rowEditor);
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll, BorderLayout.CENTER);
setPreferredSize(new Dimension(400, 120));
setLocation(150, 100);
pack();
setVisible(true);
}
public static void main(String[] args) {
EachRowEditorExample frame = new EachRowEditorExample();
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
just add EachRowEditor Class
package com.atos.table.classes;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
public class PartCustomerWindow2 {
public static final Object[][] DATA = { { 1, 2,3, 4,false }, { 5, 6,7, 8 ,true},{ 9, 10,11, 12,true }, { 13, 14,15, 16,true } };
public static final String[] COL_NAMES = { "One", "Two", "Three", "Four",MyTableModel1.SELECT };
JButton but = new JButton("Add");
private JComboBox jcomboBox = null;
private JTextField jTextField = null;
static Object[][] rowData = null;
private JTable table=null;
static JFrame frame = null;
HashMap mp = null;
static int count = 0;
String content = null;
public JTextField getjTextField() {
if(jTextField == null)
{
jTextField = new FMORestrictedTextField(FMORestrictedTextField.JUST_ALPHANUMERIC, 8);
}
mp = new HashMap();
mp.put("arif",2);
mp.put("8",6);
mp.put("12",10);
mp.put("14",16);
mp.put("pk1",22);
mp.put("pk3",23);
jTextField.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent event) {
if(count == 0)
content = jTextField.getText();
// System.out.println(content);
if(mp.containsKey(content))
{
JFrame parent = new JFrame();
JOptionPane.showMessageDialog(parent, "Already Assigned");
}
}
});
return jTextField;
}
public void setjTextField(JTextField jTextField) {
this.jTextField = jTextField;
}
public JComboBox getJcomboBox() {
if(jcomboBox == null)
{
jcomboBox = new JComboBox();
}
return jcomboBox;
}
public void setJcomboBox(JComboBox jcomboBox) {
this.jcomboBox = jcomboBox;
}
private void createAndShowGui(PartCustomerWindow2 ob)
{
/*rowData = new Object[DATA.length][];
for (int i = 0; i < rowData.length; i++) {
rowData[i] = new Object[DATA[i].length + 1];
for (int j = 0; j < DATA[i].length; j++) {
rowData[i][j] = DATA[i][j];
}
rowData[i][DATA[i].length] = Boolean.TRUE;
if(i == 2 || i ==3)
rowData[i][DATA[i].length] = Boolean.FALSE;
}*/
MyTableModel3 tableModel = new MyTableModel3(DATA, COL_NAMES, "My Table", ob);
table = new JTable(tableModel);
//table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
/*table.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) {
table.getSelectionModel().clearSelection();
}
});*/
TableColumnModel cm = table.getColumnModel();
/*cm.getColumn(2).setCellEditor(new DefaultCellEditor(
new JComboBox(new DefaultComboBoxModel(new String[] {
"Yes",
"No",
"Maybe"
}))));*/
/* String ar1[]= {"aa","aaa","aaaa"};
ob.getJcomboBox().setModel(new DefaultComboBoxModel(ar1));*/
cm.getColumn(2).setCellEditor(new DefaultCellEditor(
ob.getJcomboBox()));
cm.getColumn(3).setCellEditor(new DefaultCellEditor(
ob.getjTextField()));
JScrollPane scrollPane = new JScrollPane();
/* scrollPane.add("Table",table);
scrollPane.add("Button",but);*/
JFrame frame2 = new JFrame();
/* jcomboBox.setPreferredSize(new Dimension(100,20));
textField.setPreferredSize(new Dimension(100,20));
jcomboBox.setEnabled(false);
textField.setEnabled(false);
*/
JScrollPane scrollPane2 = new JScrollPane(but);
but.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(table.getCellEditor() != null)
table.getCellEditor().stopCellEditing();
// TODO Auto-generated method stub
String[][] ar = new String[table.getRowCount()][5];
for(int i =0;i<table.getRowCount();i++)
{
for(int j=0;j<5;j++)
{
DATA[i][j] = table.getValueAt(i,j);
}
System.out.print(table.getValueAt(i,0)+" ");
System.out.print(table.getValueAt(i,1)+" ");
System.out.print(table.getValueAt(i,2)+" ");
System.out.print(table.getValueAt(i,3)+" ");
System.out.println(table.getValueAt(i,4)+" ");
}
System.out.println("*******************");
/*
for(int i=0;i<DATA.length;i++)
{
System.out.print(DATA[i][0]);
System.out.print(DATA[i][1]);
System.out.print(DATA[i][2]);
System.out.print(DATA[i][3]);
boolean check =(Boolean) DATA[i][4];
System.out.println(check);
}*/
}});
frame = new JFrame("PartCustomerWindow2");
//
//JFrame frame = new JFrame();
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(new JScrollPane(table), BorderLayout.NORTH);
contentPane.add(but);
//
//frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* frame.getContentPane().add(scrollPane2);
frame.getContentPane().add(scrollPane3);
frame.getContentPane().add(scrollPane4);*/
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
PartCustomerWindow2 ob = new PartCustomerWindow2();
ob.createAndShowGui(ob);
}
}
#SuppressWarnings("serial")
class MyTableModel3 extends DefaultTableModel {
public static final String SELECT = "select";
String tablename;
PartCustomerWindow2 ob = null;
public MyTableModel3(Object[][] rowData, Object[] columnNames, String tableName,PartCustomerWindow2 ob) {
super(rowData, columnNames);
this.tablename = tableName;
this.ob = ob;
}
#Override
public Class<?> getColumnClass(int columnIndex) {
if (getColumnName(columnIndex).equalsIgnoreCase(SELECT)) {
return Boolean.class;
}
else
return super.getColumnClass(columnIndex);
}
#Override
public boolean isCellEditable(int row, int col) {
JComboBox jb = ob.getJcomboBox();
JTextField jt = ob.getjTextField();
if(((Boolean) getValueAt(row, getColumnCount() - 1)).booleanValue())
{
// jb.setEnabled(false);
jb.removeAllItems();
// System.out.println(jb.getItemCount());
if(row == 0)
{
jb.addItem("arif");
jb.addItem("asif");
jb.addItem("ashik");
jb.addItem("farooq");
jb.addItem("adkh");
}
if(row > 0)
{
jb.addItem("kjhds");
jb.addItem("sdds");
jb.addItem("asdfsdk");
jb.addItem("sdfsdf");
jb.addItem("sdf");
}
/*HashMap mp = new HashMap();
mp.put("arif",2);
mp.put("8",6);
mp.put("12",10);
mp.put("14",16);
mp.put("pk1",22);
mp.put("pk3",23);
*/
/* if(col == 3){
if(mp.containsKey(jt.getText()))
{
System.out.println("Sorry..!! already assigned");
jt.setFocusable(true);
}
jt.setText("");
jt.setEnabled(false);
}*/
}
else
{
// jb.setEnabled(true);
//jt.setEnabled(true);
}
if (col == getColumnCount()-1 ) {
return true;
}
else{
if (getColumnName(4).equalsIgnoreCase(SELECT) && ((Boolean) getValueAt(row, getColumnCount() - 1)).booleanValue())
{
// jb.setEnabled(true);
// jt.setEnabled(true);
return (col == 2 || col == 3);
}
else{
// jb.setEnabled(false);
//jt.setEnabled(false);
return false;
}
}
}
}