There are a lot of discussions on web on how to have hyperlinks in swing and JTable, e.g. HyperLink in JTable Cell.
The approach above is problematic because it only knows which cell the mouse is in, not the exactly text it is on, which means:
Can not handle multiple hyperlinks in the same cell;
Can not make the mouse cursor showing intuitively. Whenever the mouse is in the cell that has hyperlink, the mouse will become hand shape, even when the mouse points to some normal text or even emtpy area.
Another approach is to display JEditorPane in the cell but is also problematic because JTable only uses the JComponent returned by cell renderer to draw, I don't think the object will be sent any events. Because the default renderer will re-use the component for every cell, so it doesn't make any sense to have it handle any events.
So I wonder what's the best way to achieve the above effect.
Another approach is to display JEditorPane in the cell but is also problematic because JTable only uses the JComponent returned by cell renderer to draw, I don't think the object will be sent any events.
Try placing the cell in edit mode every time the cell gains focus. Then the editor should be display which is a real component and it should reaceive all the events. Something like:
JTable table = new JTable(...)
{
// Place cell in edit mode when it 'gains focus'
public void changeSelection(int row, int column, boolean toggle, boolean extend)
{
super.changeSelection(row, column, toggle, extend);
if (editCellAt(row, column))
{
Component editor = getEditorComponent();
editor.requestFocusInWindow();
}
}
};
I would customize the code to only edit cell for the specific column.
Related
I'm trying to implement a JXTreeTable with scrollable cells.
I used custom TableCellRenderer and it looked good, but renderer does not handle events, therefore I added an custom editor to the JXTreeTable.
I thought the cells would be editable once I override isCellEditable() and let it return true anyway but It turned out not. Cells are still not editable, thus I cannot scroll the cells even there are scroll bars.
Any ideas?
In Swing is possible to create a JComboBox in a JTable, as seen by this guide from Oracle. They have a lovely picture that shows this in action:
However, what the fail to show is that if you haven't clicked on the cell, the dropdown arrows are not visible and it just looks like a normal text label, as seen below:
You can see that knitting has dropdown arrows because I just clicked on it, but the other ones don't. This is sadly less than ideal because there are no visual cues that the cell can be clicked on to show a list of options. In other words, the "Sport" column looks identical to the "Last Name" column. One of them is a dropdown, the other is not, but they visually look the same unless you happen to click on one of them.
Is there any way that this can be done in Swing?
EDIT: To clarify, what I want is for ALL the cells in the "Sport" column to have arrows indicating a dropdown menu, even if they were not the least one clicked. Basically, I want it to look like a combo box whether I've clicked on it or not.
I'm not sure you understand the distintion between "renderer" and "edit" modes in the JTable. All the cells in the Sport column in your example are backed by a combobox, when in edit mode.
What I believe you're trying to do is something like...
Which will clutter the UI (IMHO)
So based on the example from here, I modified the code to change the default cell renderer for the Sport column
public void setUpSportColumn(JTable table,
TableColumn sportColumn) {
//Set up the editor for the sport cells.
JComboBox comboBox = new JComboBox();
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement("Snowboarding");
model.addElement("Rowing");
model.addElement("Knitting");
model.addElement("Speed reading");
model.addElement("Pool");
model.addElement("None of the above");
comboBox.setModel(model);
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
model = new DefaultComboBoxModel();
model.addElement("Snowboarding");
model.addElement("Rowing");
model.addElement("Knitting");
model.addElement("Speed reading");
model.addElement("Pool");
model.addElement("None of the above");
//Set up tool tips for the sport cells.
ComboBoxTableCellRenderer renderer
= new ComboBoxTableCellRenderer();
renderer.setModel(model);
sportColumn.setCellRenderer(renderer);
}
And added this...
public class ComboBoxTableCellRenderer extends JComboBox implements TableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setSelectedItem(value);
return this;
}
}
First of all, you may want to check this out: how to add checkbox and combobox in table cell?
In your example, I am thinking that this may be due to the fact that there is not enough height to display the GUI. What I mean is that the Swing components automatically resize to fill their container, and if the container height is too small, then it may not display the GUI correctly.
Here are images to illustrate my example (I used Windows XP):
Initial Launch:
Click on Cell:
After Cell Click:
I am a newbie to Swings
Can some on please help me
I have a scenario: in which I placed JCheck boxes in the 3rd column of JTable by overriding its column class to return Boolean for the 3rd column.
So it appears as though we have check boxes in the 3rd column of the table...... lately I discovered that the table's list selection event gets fired only based on the "cell focus" in which the check box is present but not the check box itself.
i.e if the focus is on a particular cell (of 3rd column), the toggling of check box in the cell does not fire the event....
Am I missing some thing......
in which I placed JCheck boxes in the 3rd column of JTable by
overriding its column class to return Boolean for the 3rd column.
see Oracles JTable tutorial, to try code examples from tutorial
Boolean value represents JCheckBox in JTable
i.e if the focus is on a particular cell (of 3rd column), the toggling
of check box in the cell does not fire the event....
Am I missing some thing......
have to override public boolean isCellEditable(int row, int col)
I'm currently having difficulty on adding mouse-over effect to all cells of particular column. The problem is when adding mouse listener to table, the cell-inner component doesn't get mouse event while cursor is hovering over that cell. Could you please tell me where is problem?
If I recall correctly, the cell widgets are only temporarily used to paint themselves over the correct area but i don't think they are active othewise. You should try listening to the JTable and then you can find back which cells have been clicked with rowAtPoint and columnAtPoint().
I have a custom JTable (15 rows by 20 cols) that was created to work for all JComponents. I'm currently using it for a mixture of JComboBoxes, JTextFields, and JButtons. Oh, and I'm using Java5 (a requirement).
I have two questions:
1) The first regards the TableCellRenderer class, and its single method:
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row,
final int column) {...}
All it does is cast the Object value argument to a JComponent, and potentially change the background color. No big deal. The question I have is why is this method is called sooooo often. When selecting a single cell, it is called 23 times. When Alt-Tabbing between two UNRELATED applications (I use Win7), this method is called over 200 times (and only for JButtons and JTextFields)!
Is this in any way necessary, and if not, how can I put a stop to unnecessary rendering calls?
2) The second question regards the JTable itself. When I'm editing a cell (cursor in a JTextField and blinking) and I click on another cell, that cell is only selected. If I then click on another cell, however, I start editing that cell. All I can think is that from the initial editing component, I'm selecting the JTable, and then selecting the component within. Is there any way to change this? Either going one way (always selects the jtable on first click) or the other (always enters cell on first click). I would prefer the first option, if possible.
Thansk to anyone who can grant some insight/help!
1) Why are you storing Components in the TableModel? That is not efficient. You should be storing data in the TableModel. JTable was designed to render data using a single component. The default renderer is generally a JLabel. Then when you edit a cell a different component is used.
When you click on a cell you may need to re-render the previous row (to remove the row selection) and then render the current row with the selection. So the renderer is called for each visible cell that is affected. Tabbing to the application probably causes all the visible cells to be re-rendererd.
2) Hard to answer since this is not the default behavour. You must also be using custom editors and I don't know what your custom code looks like. The default editor has a setClickCountToStart() method which defaults to 2. Maybe you set this to 1.
Change your solution to use data (not Components) in the TableModel and post your SSCCE if you have further questions.