Java GUI with JTable - java

I am displaying data in JTable through mouse event in JList. I want to know how I would change the font color of specific data after the user click in JLIst, and Here is Photo for the desired result
list.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
int solutionindex =list.getSelectedIndex();
if(solutionindex==0) {
for (int i=0;i<table.getRowCount();i++) {
for (int j=0;j<table.getColumnCount();j++) {
table.setValueAt(b.charAt(i, j), i,j);
}// end of second for loop
}// end of for loop
}
else {
for (int i=0;i<table.getRowCount();i++) {
for (int j=0;j<table.getColumnCount();j++) {
table.setValueAt(solutions.get(solutionindex1).getBoard().charAt(i, j), i,j);
}// end of second for loop
}// end of for loop
}
table.setDefaultRenderer(String.class, new DefaultTableCellRenderer(){
#Override
public java.awt.Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column) {
java.awt.Component c = super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);
c.setForeground(Color.red);
return c;
}
});

Use a ListSelectionModel instead of a MouseListener on the JList. (The JList will somewhere along the line be using the MouseListener to change state. Does it happen before or after you listener is fired? Depends. May change on implementation and even at runtime (which is really confusing).)
Switch the object in the table [model] from Character to be of a new type containing both the text and the foreground colour. In the table cell renderer, cast the cell object to the correct type, and use its colour in setForeground.

Related

Need to launch a new JPanel on click event in a JTable cell.

I want to create a JTable having the last column with advanced options icon. On clicking this last column in the JTable, I want a new JPanel to pop up allowing user to enter input for required 4 string input fields. This JPanel when dismissed, should return to the original JTable.
I am not sure where to save the data for 4 fields from the new JPanel. As their would be 4 string input fields per JTable row, just displayed in the JPanel.
Can my JTabel cell hold an object saving the data?
UseCase: I have a JTable with 10 columns. It is getting very cluttered so I want to move 5 columns to a new panel which will be launched on clicking an advanced options icon in the original JTable last column.
Sample code on how to associate the data from the JPanel with the row in JTable will be highly appreciated.
In order to show a pop-up when cell is clicked, you need a cell editor class. The main purpose of this class is to provide custom editors for cells, but you can use it to trigger some action when your cell is clicked:
public class InfoCellEditor extends AbstractCellEditor implements TableCellEditor {
#Override
public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
InfoObject info = (InfoObject) value;
editButton = new JButton(new InfoAction(info));
editButton.setText("INFO");
editButton.setEnabled(true);
}
private class InfoAction extends AbstractAction {
InfoObject info;
public InfoAction(InfoObject info) {
super();
this.info = info;
}
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, info.toString());
stopCellEditing();
}
}
}
Then, extend JTable class and implement getColumnClass and isCellEditable methods:
public class MyTable extends JTable {
public MyTable() {
super();
setDefaultEditor(InfoObject.class, new InfoCellEditor());
}
#Override
public Class getColumnClass(int columnIndex) {
if(columnIndex == 4)
return InfoObject.class;
else
return String.class;
}
#Override
public boolean isCellEditable(int row, int column) {
if(column == 4)
return true;
else
return false;
}
}
Lastly, you should make sure that InfoObject instances are inserted to 5th column. And you can also implement a TableCellRenderer for some custom visual representation of that column.
Object headers = new Object[COLUMN_COUNT];
Object cells[][] = new Object[ROW_COUNT][];
...
cells[0][4] = new InfoObject(data[0]);
cells[1][4] = new InfoObject(data[1]);
table.setModel(new DefaultTableModel(cells, headers));
table.getModel().fireTableDataChanged();
table.setVisible();

How to add JCheckBox beside a String in JList and allows it to select and open multiple files stored in a folder without the use of ctrl key? [duplicate]

What would be the best way to have a list of items with a checkbox each in Java Swing?
I.e. a JList with items that have some text and a checkbox each?
A wonderful answer is this CheckBoxList. It implements Telcontar's answer (though 3 years before :)... I'm using it in Java 1.6 with no problems. I've also added an addCheckbox method like this (surely could be shorter, haven't used Java in a while):
public void addCheckbox(JCheckBox checkBox) {
ListModel currentList = this.getModel();
JCheckBox[] newList = new JCheckBox[currentList.getSize() + 1];
for (int i = 0; i < currentList.getSize(); i++) {
newList[i] = (JCheckBox) currentList.getElementAt(i);
}
newList[newList.length - 1] = checkBox;
setListData(newList);
}
I tried out the demo for the Jidesoft stuff, playing with the CheckBoxList I encountered some problems (behaviors that didn't work). I'll modify this answer if I find problems with the CheckBoxList I linked to.
Create a custom ListCellRenderer and asign it to the JList.
This custom ListCellRenderer must return a JCheckbox in the implementantion of getListCellRendererComponent(...) method.
But this JCheckbox will not be editable, is a simple paint in the screen is up to you to choose when this JCheckbox must be 'ticked' or not,
For example, show it ticked when the row is selected (parameter isSelected), but this way the check status will no be mantained if the selection changes. Its better to show it checked consulting the data below the ListModel, but then is up to you to implement the method who changes the check status of the data, and notify the change to the JList to be repainted.
I Will post sample code later if you need it
ListCellRenderer
Just implement a ListCellRenderer
public class CheckboxListCellRenderer extends JCheckBox implements ListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
setComponentOrientation(list.getComponentOrientation());
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
setSelected(isSelected);
setEnabled(list.isEnabled());
setText(value == null ? "" : value.toString());
return this;
}
}
and set the renderer
JList list = new JList();
list.setCellRenderer(new CheckboxListCellRenderer());
this will result in
Details at Custom swing component renderers.
PS: If you want radio elements just replace extends JCheckbox with extends JRadioButton.
I'd probably be looking to use a JTable rather than a JList and since the default rendering of a checkbox is rather ugly, I'd probably be looking to drop in a custom TableModel, CellRenderer and CellEditor to represent a boolean value. Of course, I would imagine this has been done a bajillion times already. Sun has good examples.
Better solution for Java 7 and newer
I stumbled upon this question and realized that some of the answers are pretty old and outdated. Nowadays, JList is generic and thus there are better solutions.
My solution of the generic JCheckBoxList:
import java.awt.Component;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
#SuppressWarnings("serial")
public class JCheckBoxList extends JList<JCheckBox> {
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
public JCheckBoxList() {
setCellRenderer(new CellRenderer());
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int index = locationToIndex(e.getPoint());
if (index != -1) {
JCheckBox checkbox = (JCheckBox) getModel().getElementAt(index);
checkbox.setSelected(!checkbox.isSelected());
repaint();
}
}
});
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
public JCheckBoxList(ListModel<JCheckBox> model){
this();
setModel(model);
}
protected class CellRenderer implements ListCellRenderer<JCheckBox> {
public Component getListCellRendererComponent(
JList<? extends JCheckBox> list, JCheckBox value, int index,
boolean isSelected, boolean cellHasFocus) {
JCheckBox checkbox = value;
//Drawing checkbox, change the appearance here
checkbox.setBackground(isSelected ? getSelectionBackground()
: getBackground());
checkbox.setForeground(isSelected ? getSelectionForeground()
: getForeground());
checkbox.setEnabled(isEnabled());
checkbox.setFont(getFont());
checkbox.setFocusPainted(false);
checkbox.setBorderPainted(true);
checkbox.setBorder(isSelected ? UIManager
.getBorder("List.focusCellHighlightBorder") : noFocusBorder);
return checkbox;
}
}
}
For dynamically adding JCheckBox lists you need to create your own ListModel or add the DefaultListModel.
DefaultListModel<JCheckBox> model = new DefaultListModel<JCheckBox>();
JCheckBoxList checkBoxList = new JCheckBoxList(model);
The DefaultListModel are generic and thus you can use methods specified by JAVA 7 API here like this:
model.addElement(new JCheckBox("Checkbox1"));
model.addElement(new JCheckBox("Checkbox2"));
model.addElement(new JCheckBox("Checkbox3"));
I recommend you use a JPanel with a GridLayout of 1 column. Add the checkBoxes to the JPanel, and set the JPanel as the data source of a JScrollPane. And to get the selected CheckBoxes, just call the getComponents() of the JPanel to get the CheckBoxes.
Odds are good w/ Java that someone has already implemented the widget or utility you need. Part of the benefits of a large OSS community. No need to reinvent the wheel unless you really want to do it yourself. In this case it would be a good learning exercise in CellRenderers and Editors.
My project has had great success with JIDE. The component you want, a Check Box List, is in the JIDE Common Layer (which is OSS and hosted on java.net). The commercial stuff is good too, but you don't need it.
http://www.jidesoft.com/products/oss.htm
https://jide-oss.dev.java.net/
I don't like the solutions that put a Checkbox into the model. The model should only contain data not display elements.
I found this http://www.java2s.com/Tutorials/Java/Swing_How_to/JList/Create_JList_of_CheckBox.htm
which I optimized a bit. The ACTIVE flag represents the Checkbox, the SELECTED flag shows what entry the cursor sits on.
my version requires a renderer
import java.awt.Component;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
class CheckListRenderer extends JCheckBox implements ListCellRenderer<Entity> {
#Override
public Component getListCellRendererComponent(JList<? extends Entity> list,
Entity value, int index, boolean isSelected, boolean cellHasFocus) {
setEnabled(list.isEnabled());
setSelected(value.isActive()); // sets the checkbox
setFont(list.getFont());
if (isSelected) { // highlights the currently selected entry
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setText(value.toString()+" - A" + value.isActive()+" - F"+cellHasFocus+" - S"+isSelected );
return this;
}
}
and an entity that got the active field:
public class Entity {
private boolean active = true;
public boolean isActive() {
return active;
}
public void setActive(boolean isActive) {
this.active = isActive;
}
}
Now you only have to add this to your JList:
list = new JList<Entity>();
list.setModel(new DefaultListModel<Entity>());
list.setCellRenderer(new CheckListRenderer());
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent event) {
if (event.getX() < 20) {
// Quick and dirty: only change the tick if clicked into the leftmost pixels
#SuppressWarnings("unchecked")
JList<Entity> list = ((JList<Entity>) event.getSource());
int index = list.locationToIndex(event.getPoint());// Get index of item clicked
if (index >= 0) {
Entity item = (Entity) list.getModel().getElementAt(index);
item.setActive(!item.isActive()); // Toggle selected state
list.repaint(list.getCellBounds(index, index));// Repaint cell
}
}
}
});
All of the aggregate components in Swing--that is, components made up other components, such as JTable, JTree, or JComboBox--can be highly customized. For example, a JTable component normally displays a grid of JLabel components, but it can also display JButtons, JTextFields, or even other JTables. Getting these aggregate components to display non-default objects is the easy part, however. Making them respond properly to keyboard and mouse events is a much harder task, due to Swing's separation of components into "renderers" and "editors." This separation was (in my opinion) a poor design choice and only serves to complicate matters when trying to extend Swing components.
To see what I mean, try enhancing Swing's JList component so that it displays checkboxes instead of labels. According to Swing philosophy, this task requires implementing two interfaces: ListCellRenderer (for drawing the checkboxes) and CellEditor (for handling keyboard and mouse events on the checkboxes). Implementing the ListCellRenderer interface is easy enough, but the CellEditor interface can be rather clumsy and hard to understand. In this particular case, I would suggest forgetting CellEditor entirely and to handle input events directly, as shown in the following code.
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class CheckBoxList extends JList
{
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
public CheckBoxList()
{
setCellRenderer(new CellRenderer());
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
int index = locationToIndex(e.getPoint());
if (index != -1) {
JCheckBox checkbox = (JCheckBox)
getModel().getElementAt(index);
checkbox.setSelected(
!checkbox.isSelected());
repaint();
}
}
}
);
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
protected class CellRenderer implements ListCellRenderer
{
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus)
{
JCheckBox checkbox = (JCheckBox) value;
checkbox.setBackground(isSelected ?
getSelectionBackground() : getBackground());
checkbox.setForeground(isSelected ?
getSelectionForeground() : getForeground());
checkbox.setEnabled(isEnabled());
checkbox.setFont(getFont());
checkbox.setFocusPainted(false);
checkbox.setBorderPainted(true);
checkbox.setBorder(isSelected ?
UIManager.getBorder(
"List.focusCellHighlightBorder") : noFocusBorder);
return checkbox;
}
}
}
Here, I intercept mouse clicks from the listbox and simulate a click on the appropriate checkbox. The result is a "CheckBoxList" component that is both simpler and smaller than an equivalent component using the CellEditor interface. To use the class, simply instantiate it, then pass it an array of JCheckBox objects (or subclasses of JCheckBox objects) by calling setListData. Note that the checkboxes in this component will not respond to keypresses (i.e. the spacebar), but you could always add your own key listener if needed.
Source: DevX.com
Here is just a little addition to the JCheckBoxList by Rawa. This will add the ability to select using space bar. If multiple items are selected, all will be set to inverted value of the first item.
addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
int index = getSelectedIndex();
if (index != -1 && e.getKeyCode() == KeyEvent.VK_SPACE) {
boolean newVal = !((JCheckBox) (getModel()
.getElementAt(index))).isSelected();
for (int i : getSelectedIndices()) {
JCheckBox checkbox = (JCheckBox) getModel()
.getElementAt(i);
checkbox.setSelected(newVal);
repaint();
}
}
}
});
this is yet another example of making list with checkboxes
class JCheckList<T> extends JList<T> {
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
public void setSelected(int index) {
if (index != -1) {
JCheckBox checkbox = (JCheckBox) getModel().getElementAt(index);
checkbox.setSelected(
!checkbox.isSelected());
repaint();
}
}
protected static class CellListener
extends DefaultListModel
implements ListDataListener {
ListModel ls;
public CellListener(ListModel ls) {
ls.addListDataListener(this);
int i = ls.getSize();
for (int v = 0; v < i; v++) {
var r = new JCheckBox();
r.setText(ls.getElementAt(v).toString());
this.addElement(r);
}
this.ls = ls;
}
#Override
public void intervalAdded(ListDataEvent e) {
int begin = e.getIndex0();
int end = e.getIndex1();
for (; begin <= end; begin++) {
var r = new JCheckBox();
r.setText(ls.getElementAt(begin).toString());
this.add(begin, r);
}
}
#Override
public void intervalRemoved(ListDataEvent e) {
int begin = e.getIndex0();
int end = e.getIndex1();
for (; begin <= end; end--) {
this.remove(begin);
}
}
#Override
public void contentsChanged(ListDataEvent e) {
}
}
public JCheckList() {
setCellRenderer(new CellRenderer());
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int index = locationToIndex(e.getPoint());
setSelected(index);
}
}
);
addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE){
int index = JCheckList.this.getSelectedIndex();
setSelected(index);
}
}
#Override
public void keyReleased(KeyEvent e) {
}
});
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
#Override
public void setModel(ListModel<T> d) {
var r = new CellListener(d);
d.addListDataListener(r);
super.setModel(r);
}
protected class CellRenderer implements ListCellRenderer {
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JCheckBox checkbox = (JCheckBox) value;
checkbox.setBackground(isSelected
? getSelectionBackground() : getBackground());
checkbox.setForeground(isSelected
? getSelectionForeground() : getForeground());
checkbox.setEnabled(isEnabled());
checkbox.setFont(getFont());
checkbox.setFocusPainted(false);
checkbox.setBorderPainted(true);
checkbox.setBorder(isSelected
? UIManager.getBorder(
"List.focusCellHighlightBorder") : noFocusBorder);
return checkbox;
}
}
}

Text disappear after Component change size

I create a jTable, and TableCellRenderer, TableCellEditor on it. I need to put there editable (with text/html context type) JEditorPane. When i write some text inside and resize component, text disappear. What I doing wrong? Furthermore above this component I have got buttons with text edition: for example:
JButton bold = new JButton():
bold.setAction(new StyledEditorKit.BoldAction());
It is part of my custom model:
private JEditorPane editorTxtPane = new JEditorPane("text/html", "");
private JEditorPane rendererTxtPane = new JEditorPane("text/html", "");
private final JPanel editorPanel = new JPanel();
private final JPanel rendererPanel = new JPanel();
private final ArrayList<FocusListener> editorFocusListeners = new ArrayList<FocusListener>();
public SampleModel() {
super();
rendererTxtPane.setContentType("text/html");
editorTxtPane.setContentType("text/html");
rendererPanel.add(initCellControls(rendererPanel, rendererLabel));
rendererPanel.add(rendererTxtPane);
editorPanel.add(initCellControls(editorPanel, editorLabel));
JScrollPane sp = new JScrollPane(editorTxtPane);
sp.setBorder(null);
editorPanel.add(sp);
editorTxtPane.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
super.focusGained(e);
e.setSource(editorTxtPane);
for (int i = editorFocusListeners.size() - 1; i >= 0; i--) {
editorFocusListeners.get(i).focusGained(e);
}
}
#Override
public void focusLost(FocusEvent e) {
super.focusLost(e);
e.setSource(editorTxtPane);
for (int i = editorFocusListeners.size() - 1; i >= 0; i--) {
editorFocusListeners.get(i).focusLost(e);
}
}
});
}
It is my editor and renderer methods:
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Comment c = data.get(row);
rendererTxtPane.setText(c.getComment());
return rendererPanel;
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
Comment c = data.get(row);
c.setNeedSave(true);
editorTxtPane.setText(c.getComment());
return editorPanel;
}
This is not how Editors and Renderers work. In particular, the editor is only valid while the cell is being edited. Your TableModel should store each row's Document. After editing concludes, your model will be updated with the revised Document, as described here. You might compare what your doing with the example, which could form the basis of your sscce.
This may be the result of one of the two conditions below:
The text component that you are embedding in your resisable
component is being shifted out through the process of resising
mechanism, so when you are resising it, the inner text component is
disappearing
Whenever the resising process is happening, the standard Swing
repaint process is not being called by he platform, in the right moment, so you can
call repaint manually through coding. The SWING platfrom usually
calls the repaint method automatically whenever it notices a change in
the overall GUI, but it's schedulled to be run after some other
processes to complete, in this case calling repaint manually is
inevitble

JTable Cell Update doesn't work

In my application I have use a java table which is similar to this example. My problem is when I change a value of a cell (even in above example) the data model doesn't get updated until I click on a different cell. Even I click on the gray area below the table after changing the cell value the model won't change. I think the reason is cell stay on focused until I click on a different cell. How can I avoid this and update the model without clicking on the table cell. Thanks in advance
I have edit the above sample code to reflect the problem
public class JTableDemo extends JApplet {
private JTextArea txt = new JTextArea(4, 20);
// The TableModel controls all the data:
class DataModel extends AbstractTableModel {
Object[][] data = { { "one", "two", "three", "four" },
{ "five", "six", "seven", "eight" },
{ "nine", "ten", "eleven", "twelve" }, };
// Prints data when table changes:
class TML implements TableModelListener {
public void tableChanged(TableModelEvent e) {
txt.setText(""); // Clear it
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[0].length; j++)
txt.append(data[i][j] + " ");
txt.append("\n");
}
}
}
public DataModel() {
addTableModelListener(new TML());
fireTableDataChanged();
}
public int getColumnCount() {
return data[0].length;
}
public int getRowCount() {
return data.length;
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
public void setValueAt(Object val, int row, int col) {
data[row][col] = val;
System.out.println(val);
// Indicate the change has happened:
fireTableDataChanged();
}
public boolean isCellEditable(int row, int col) {
return true;
}
}
public void init() {
Container cp = getContentPane();
JTable table = new JTable(new DataModel());
cp.add(new JScrollPane(table));
cp.add(BorderLayout.SOUTH, txt);
}
public static void main(String[] args) {
run(new JTableDemo(), 350, 200);
}
public static void run(JApplet applet, int width, int height) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(applet);
frame.setSize(width, height);
applet.init();
applet.start();
frame.setVisible(true);
}
}
When you run the example you can see the table content in the text area below the table. After you update a cell it should appear in the text box below. But 'setValueAt' method wont call until you click on a different cell.
That's expected behaviour: the edited value isn't committed to the backing model until an explicit user gesture, like f.i. pressing enter or tabbing out or clicking elsewhere in the table ...
One oddity (some call it bug :-) of JTable is that editing isn't by default terminated when transfering focus to the "outside" of the table. To force it doing so, you need to configure it like:
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
BTW (unrelated, just for sanity): always fire the most fine-grained event type, here that would be a cellUpdated instead of the dataChanged hammer.
The default update mechanism only changes the model when the cell editor loses the focus. Either tabbing out of the cell or clicking in a different cell will cause the vital "focus lost" event which triggers the model change.
Clicking in the gray area has no effect because there are no active elements there which could process the event - the table ignores the click.
If you want to change this, you need to find an event which tells the computer that the user is "done with editing". How do you know that?
You could add an ActionListener (see http://download.oracle.com/javase/tutorial/uiswing/components/textfield.html). It will get triggered when you press RETURN. In the handler, call fireEditingStopped() to trigger the "copy to model" code (see http://download.oracle.com/javase/tutorial/uiswing/components/table.html#editor).
You could add a "Save" button below the table and call this code in it's ActionListner:
if(null != jTable.getCellEditor()) {
// there is an edit in progress
jTable.getCellEditor().stopCellEditing()
}
You could update the model for each keypress by adding a keypress handler but that might cause the editor to disappear.
[EDIT] Note that adding a "Save" button can disrupt the edit "flow" of users (click table cell, edit, grab mouse, aim, click save, click next cell, go back to keyboard, edit, ...)
For my case
public void setValueAt(Object val, int row, int col) {
data[row][col] = val;
System.out.println(val);
// Indicate the change has happened:
fireTableDataChanged();
}
you need to call super function also.
public void setValueAt(Object val, int row, int col) {
data[row][col] = val;
System.out.println(val);
// Indicate the change has happened:
fireTableDataChanged();
super.setValueAt(val,row,col);
}

How can I make a JTable cell do different things on single-click than on double-click?

I am using an editable JTable that contains a column named Subject. When the first row is empty and the user clicks on a subject cell to add new task, by default, the user has to click twice to make the cell editable. I want to make it editable on single-click and have it open another form on double-click. I have tried MouseListener but have not been able to solve it. Is there a way to solve this problem? If so, what is it?
My code:
class mouseRenderer extends DefaultTableCellRenderer {
JLabel lblcell = new JLabel();
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row,
int column) {
ttable.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
selrow = ttable.getSelectedRow();
selcol = ttable.getSelectedColumn();
if(e.getClickCount() == 1) {
if(selrow == 0) {
lblcell.setText("");
}
}
}
});
return lblcell;
}
}
For the one-click to edit, you could try the 'setClickCountToStart()' method of the celleditor used in your jtable.
You can try to create a custom CellEditor like this one and set it with setCellEditor()
public class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {
public boolean isCellEditable(EventObject evt) {
if (evt instanceof MouseEvent) {
int clickCount;
// For single-click activation
clickCount = 1;
// For double-click activation
clickCount = 2;
// For triple-click activation
clickCount = 3;
return ((MouseEvent)evt).getClickCount() >= clickCount;
}
return true;
}
}
The MouseListener is the way to go for capturing double clicks on a row. It should work fine.
As far as one-click to edit, you might want to select rows using a MouseMotionListener and let the JTable take the single-click to edit. Another option might be to use a MouseListener to detect the cell that was clicked, but that is getting a little messy.

Categories