Creating a JComboBox in a JTable with the dropdown always visible - java

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:

Related

Displaying just one value in JComboBox when one is selected

Hello :) I need help with changing a JComboBox in a JTable. I'm new to GUI-Programming and Swing and couldn't solve this problem: I have to change the behavior of a JComboBox.
You can see the ComboBox in the picture below. If "Ja" is selected there should just be "Nein" as an option and the other way around. It would also be cool if "Nein" is set per default. The code was written from one student from last semester and I have difficulties to adjust the combobox like I have to.
That's the code snippet where the ComboBox gets initialized.
optionsInteger = new JComboBox<String>();
optionsInteger.addItem("Ja");
optionsInteger.addItem("Nein");
optionsInteger.setSelectedItem(optionsInteger.getItemAt(0));
optionsInteger.setSelectedIndex(1);
optionsInteger.setName("optionsInteger");
The ComboBox gets inserted to a JTable in this method:
public void repaintXTable(DefaultTableModel model,JTable table, int xAmount, JScrollPane scrollPane,
JComboBox<String> optionsInteger) {
model.setRowCount(xAmount);
th = table.getTableHeader();
tcm = th.getColumnModel();
tcs = tcm.getColumns();
tcs.nextElement().setHeaderValue("");
tcs.nextElement().setHeaderValue("Lower");
tcs.nextElement().setHeaderValue("Upper");
tc = tcs.nextElement();
tc.setHeaderValue("Integer");
tc.setCellEditor(new DefaultCellEditor(optionsInteger));
for(int i=0;i<xAmount;i++)
{
model.setValueAt("X"+(i+1), i, 0);
}
}
Thank you very much for your help.
In your code, this line
optionsInteger.setSelectedItem(optionsInteger.getItemAt(0));
sets the default selection to the zeroth element (Ja). This line
optionsInteger.setSelectedIndex(1);
sets the default selection to the first element (Nein).
Either set the selected item or the selected index. There's no need to do both.
A JComboBox does not remove the selected element by default. If the selected element is removed, how would the selected element display in your JTable?
If you really want to do this, you'll have to create your own version of a JComboBox.
. If "Ja" is selected there should just be "Nein" as an option and the other way around.
So then you need two separate ComboBoxModels, one model containing "Nein" and the other containing "Ja". Then when you start to edit the cell you check the current value and use the model containing the other value.
Check out How to add unique JComboBoxes to a column in a JTable (Java). This example shows how you can dynamically change the model at the time the cell is about to be edited.
It would also be cool if "Nein" is set per default.
This has nothing to do with the editor. You just add "Nein" to the TableModel when you add the data to the model.

JCheck box when placed in JTable cell not responding to mouse clicks

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)

2 column jcombobox

I had quite a lot use for a multicolumn jcombobox, but have not yet found any nor managed to make my own. I have tried several approaches found in web, but they have not worked. Afterwards I read somewhere that those (old) does not work under current Java version.
I have managed to make my own so far, that the combobox has a table as dropdown list and I can select an item with mouse, but the goal is that when the user starts to type into the edit box, drop down list opens and cursor moves based on the text the user has written. It seems that the events from e.g. JTextField editor = (JTextField) comboBox.getEditor().getEditorComponent() does not work.
Has anybody managed to make a two column combobox or have any ideas, how I could get the event when the user starts to type.
You are looking for autocomplete functionality (as I understand the question): it's supported in SwingX - and quite easy to use.
It boils down to implemneting a custom ObjectToStringConverter and configure the comboBox with an autoCompleteDecorator using that converter. Something like:
/**
* A converter which expects an item of an array type and returns
* a string representation of its first value.
*/
public static class ArrayToStringConverter extends ObjectToStringConverter {
#Override
public String getPreferredStringForItem(Object item) {
if (!(item instanceof Object[])) return DEFAULT_IMPLEMENTATION.getPreferredStringForItem(item);
Object[] array = (Object[]) item;
return DEFAULT_IMPLEMENTATION.getPreferredStringForItem(array[0]);
}
}
// usage
// assuming an model with items being arrays
JComboBox combo = new JComboBox(arrayModel);
// the renderer supporting multiple columns, f.i. a table
combo.setCellRenderer(new TabularListRenderer());
AutoCompleteDecorator.decorate(combo, new ArrayToStringConverter());
A complete working example (including the renderer and showing how-to force the width of the popup to be larger than the combo itself) is TableAsListRenderer in my incubator section
BTW: the autocomplete functionality is a standalone module, accessible via maven or manually downloadable from the maven rep at java.net, you would want the swingx-autocomplete-1.6.4.jar (plus the corresponding doc/sources, if interested)
Has anybody managed to make a two column combobox or have any ideas, how I could get the event when the user starts to type.
you can to put JTable to the JComboBox, but by default you can to select only value from entire JTables row, not directly from JTables Cell (required additional workaround, not tried yet)
i still searching for this answer too
here's i try so far..
i create Jpopup and put the Jtable in there..
then i use jlabel not jcombobox,
when user click jlabel, then the popup(Jtable) will show in that jlabel location..
when user select value on jtable,
then the popup will dispose,
then the jlabel will show the result..
for your case, you can use jtextfield not jlabel
EDIT :
heres related question
enter link description here

In JTable cell, how to handle multiple hyperlinks correctly?

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.

Item always selected in JTable

I have created a JTable where the included items are provided with radio buttons in order to enable users to select any of these once at a time. In order to show always the first item selected when the JTable is initialised (or when the item previously selected has been deleted) what method should I use?
You should see the JTable Javadoc and particularly at :
getCellRect(int row, int column, boolean includeSpacing)
and
scrollRectToVisible(Rectangle aRect)
Something like
table.scrollRectToVisible(table.getCellRect(table.getSelectedRows()[0], 0, true));
should suit you.

Categories

Resources