Multiline JTable Cells are not multilined during editing - java

I'm developing an app which has an JTable that needs to have multiline cells. Therefore I extended JTextArea and everything is shown noce, but when I try to edit a cell. the text is shown in a single line, and becomes multilined after edit. I want the text to stay multilined during editting.
Is there a way to do that?

Create your TableCellEditor using a JTextArea (instead of the default behaviour which uses JTextField) and set it to your JTable.
You can use a JEditorPane as well to support text styling, if you wish.
---- Edit2 ----
New TableCellEditor:
class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {
JComponent component = new JTextArea();
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
int rowIndex, int vColIndex) {
((JTextArea) component).setText((String) value);
return component;
}
public Object getCellEditorValue() {
return ((JTextArea) component).getText();
}
}

Related

How to make the JComboBox dropdown always visible in a JTable

I'm using JComboBox with JTables, but the dropdown menu is only "visible" when it's clicked. How can I change this default behavior and make it always visible and user-friendly?
public void start(){
TableColumn column = table.getColumnModel().getColumn(0);
JComboBox comboBox = new JComboBox();
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement("a");
model.addElement("b");
comboBox.setModel(model);
}
As I understand it, you would like the cells to always look like JComboBoxes, and not jLabels.
This can easily be accomplished by adding a TableCellRenderer to your TableColumn.
Pasting in the following code should have the desired effect.
column.setCellRenderer(new TableCellRenderer() {
JComboBox box = new JComboBox();
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
box.removeAllItems();
box.addItem(value.toString());
return box;
}
});

How do I add a JLabel[] to a JTable?

I have an array of JLabels which I want to add to a JTable. I tried using
myJTable.add(myJLabelArray);
Hoping it would work, but it doesn't (Obviously, otherwise I wouldn't be here).
Can somebody please help?
Using add method is not the way to add components to a JTable. Components should never be added directly to a JTable or its TableModel.
JLabels are just Swing components that render text.
You can use a TableCellRenderer. Have a look at Editors & Renderers
You cannot just add myJTable.add(myJLabelArray). As Reimeus pointed out use Renderers
jTable1.getColumnModel().getColumn(0).setCellRenderer(new Renderer()); //set column1 with jlabel
Your render should extend DefaulttableCellRenderer
class Renderer extends DefaultTableCellRenderer {
JLabel lbl = new JLabel();
//ImageIcon icon = new ImageIcon(getClass().getResource("sample.png"));
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
lbl.setText("hello");
//lbl.setIcon(icon);
return lbl;
}
}

Color of the dropdown control and border in an uneditable JComboBox

The background color of the selected item in an uneditable JComboBox is a sort of blue:
I know that you can change it to a different color, such as white, for example with the following code:
jComboBox1.setRenderer(new DefaultListCellRenderer() {
#Override
public void paint(Graphics g) {
setBackground(Color.WHITE);
setForeground(Color.BLACK);
super.paint(g);
}
});
That gives you something like this:
However, if you double-click on that combo-box, some of it turns gray (the part with the triangle and the border):
Is there a way to stop these parts from turning gray when you double-click on it?
Note that, if you call super.paint() first, the whole thing turns dark (including the part behind "Select..."), so that doesn't help.
Not sure what exactly OP is trying to achieve, but here is my JComboBox coloring recipe:
static public void main(String[] args) {
JFrame window = new JFrame("Coloring ComboBox");
window.setSize(170, 150);
window.setLocationRelativeTo(null);
window.setLayout(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//---textArea is just for focus switching
JTextArea textArea = new JTextArea();
textArea.setBounds(5, 5, 140, 25);
window.add(textArea);
UIManager.put("ComboBox.selectionBackground", Color.magenta); //---focused background color
//---see comboBox's UIDefaults for more tweaks
JComboBox<String> coloredCombo = new JComboBox<String>(new String[]{"Dog", "Cat", "Bird"});
coloredCombo.setEditable(false);
coloredCombo.setUI(new BasicComboBoxUI() {
#SuppressWarnings({"serial"})
#Override
protected ComboPopup createPopup() {
return new BasicComboPopup(coloredCombo) {
{
//---style popup anyway you like
this.setBorder(BorderFactory.createLineBorder(Color.green, 2));//---popup's border color
}
};
}
#Override
protected JButton createArrowButton() {
//---style arrow button anyway you like
JButton result = new JButton();
result.setBackground(Color.orange);//---button's color
return result;
}
});
coloredCombo.setBorder(BorderFactory.createLineBorder(Color.red, 2));//---border color
coloredCombo.setBackground(Color.yellow); //---not focused background color
coloredCombo.setRenderer(new ListCellRenderer<String>() {
#Override
public Component getListCellRendererComponent(JList<? extends String> list, String value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel result = new JLabel(value);
result.setOpaque(true);
result.setBackground(isSelected ? Color.cyan : Color.blue); //---item background color
return result;
}
});
coloredCombo.setBounds(5, 35, 140, 25);
window.add(coloredCombo);
window.setVisible(true);
}
Of course, this is just an axample, I recommend you to create a fancy custom class to reuse.
A couple things:
The appearance of the combobox (the display area, the arrow, the drop down) are LAF dependent. Your screen shots suggest WinXP. If you must support any other LAFs, be sure to test that as well, because what works for one LAF may not work for another. I have found this to be particularly true for JComboBoxes.
Like Twister suggests, changing the color by overriding the paint() method likely isn't the best way to do this. Just set the background/foreground color of the combobox itself. If you want to change the color of the dropdown itself (I'm not clear if you want to do this or not), then add a custom renderer that overrides getListCellRendererComponent to set the background/foreground.
public static class CustomRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
setBackground(Color.WHITE);
setForeground(Color.BLACK);
return this;
}
}
The appearance of the grey triangle and border is because the combo box now has focus. You can just make it not focusable, and the coloring will go away. This may not be the behavior you want, however.
JComboBox combo = new JComboBox(new Object[]{"Dog", "Cat", "Bird"});
combo.setBackground(Color.WHITE);
combo.setForeground(Color.BLACK);
combo.setFocusable(false);
First, you should not set the foreground and background in the paint method. You should override the getListCellRendererComponent of your renderer in order to customize it. The default renderer change its aspect if you it has the focus or if it is selected. If you do not want those features reimplements the method.
Then if you add a line border to your renderer (setBorder(BorderFactory.createLineBorder(Color.black)) you will see that what is drawn is not part of your renderer but the combobox itself. So you might have to customize the UI
The swing code that calls getListCellRendererComponent, then calls setForeground and setBackground on the returned component (depending on the whether the component is selected and/or focused). I assume this is for some legacy behavior. Unfortunately, it defeats the purpose of my setting it in the renderer.
I've had some good results with this approach:
The code below circumvents changing the foreground and background by overriding the fg/bg setters to do nothing, then I just call the super implementations to set the colors I want.
public static class CustomRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
super.setBackground(Color.WHITE);
super.setForeground(Color.BLACK);
return this;
}
public void setForeground(Color c) {}
public void setBackground(Color c) {}
}
Addendum:
The grey border is probably just that, a border. Try the same approach, but also override setBorder.

Adding button to a jtable

I am having a table in which i have to adda JButton.
I am doing
TableColumnModel colModel = table.getColumnModel();
colModel.getColumn(0).setCellEditor(new MYCellEditor(new JCheckbox()));
MyCellEditor extends DefaultCellEditor{
public MyCellEditor(JCheckbox checkbox){
super(checkbox);
Jbutton button = new JButton("Start");
//actionlistener for button.
}
}
MyRenderer extends DefaultTablecellRenderer{
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
//return a button for column ==0
}
My understanding is that the Celleditor has same instance of button for all cells in a column. So if i click on one button the text changes from "Start" to "stop" but if i click on button in other row it doesnt work.. After debugging it shows that the text is alreadt Stop .
How can i have different instance of button in each row ?
The article Table Button Column cited in #camickr's previous answer provides a more flexible solution, but you may find the tutorial How to Use Tables: Using Other Editors helpful, too. The ColorEditor discussed there is part of the TableDialogEditDemo, available via Java Web Start. You'll need to change the corresponding ColorRenderer accordingly.

JCombobox, Editor and Renderer related

As a JCombobox ListCellRenderer, I have a class like this one:
class ZComboBoxRenderer extends JPanel implements ListCellRenderer{
private ZGrid grid;
public ZComboBoxRenderer(ZGrid grid) {
setLayout(new BorderLayout());
this.grid = grid;
add(new JScrollPane(grid), BorderLayout.CENTER);
}
public ZGrid getGrid(){
return grid;
}
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
grid.fetchSQL();
return this;
}
}
ZGrid here, extends JTable.
As a ListCellRendererComponent, I provide a JPanel which has a ZGrid inside, to the JCombobox. The problem is, in its list, this ZGrid is painting properly. But it is also being painted inside the Editor of JCombobox. I have uploaded an image to show this better.
Is there a way to separate Editor from List?
alt text http://img444.imageshack.us/img444/564/soex.jpg
From what I understand, you are implementing a custom Renderer for your JComboBox, and though it correctly renders the contents of your dropdown, it completely messes up the current value of the combo box.
I see two options at your disposal:
you can extend the UI component for your JComboBox and override the paint method to get a custom representation of your grid for your current value view. This would be a pretty quick proof of concept, but it poses issues as you would need to extend every UI (metal, windows, mac, etc) that you expect your app to be running with.
you can roll your own dropdown, and make it look like a JComboBox. This would not be that difficult to do as a POC as well, but the complexity here is to handle the different keyboard inputs that influence the selection and navigation around the combo box.

Categories

Resources