Using TableCellRenderer in XdevSortableTable, XdevAggregateTable - java

Well, I'm trying to render some components in the tables mentioned above. I know thats done with implementing a custom TableCellRenderer, and that works just fine in normal JTable, e.g. doing something like this:
import java.awt.Component;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
public class Test
{
public static void main(String[] argv)
{
String[] columnNames = {"First Name","Last Name","nr"};
Object[][] data = {{"Homer","Simpson","1"},{"Madge","Simpson","2"},{"Bart","Simpson","3"},
{"Lisa","Simpson","4"},};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
JTable table = new JTable(model);
table.getColumnModel().getColumn(2).setCellRenderer(new TableCellRenderer(){
final JButton button = new JButton();
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
button.setText(value.toString());
return button;
}
});
JFrame f = new JFrame();
f.setSize(300,300);
f.add(new JScrollPane(table));
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
It also works with JIDE's Sortable- and AggregateTable, but as soon as I replace those tables with Xdev's, the component isn't rendered anymore, so it seems the CellRenderer isn't set properly, even though TableColumn.getCellRenderer() returns the correct class.
So does anyone know how to render a component in Xdev's tables?
Thanks in advance!

Related

How to give keyboard focus to Custom panel in JTable?

I am working on making the Arduino IDE fully accessible for people using access software. This means adding keyboard accessibility to two of the dialogs that currently do not work with access software under windows. The two dialogs are the Board Manager and the LibraryManager. If you want a real example of what I am posting you can get teh Arduino IDE on the Windows Store or download it on line. Just search for Arduino IDE and download the windows version. .
doing all that might be to much for most of you so I have created a more simple table that shows the same problem. If someone can help me understand how to add keyboard and focus access to the below Custom JTable and its custom column which is a JPanel I can work on fixing the Arduino IDE tables.
I understand that the Arduino IDE should probably be made into a
better table but I have yet to figure out a cleaner way to do what they are doing with these tables so I am trying to make what they have accessible.
So below is my problem table. It has two rows and two columsn. The
second column of each row is a panel of controls. I have borrowed
this code from some other stack posts and modified it to fit my
question. So if you think you have seen some of this code before that
is why. The problem is the code works for a mouse. At least I think
it does because I am blind and can not select the controls on the
second column because they can not get keyboard focus.
So Can someone out there help me figure out how to get keyboard focus
to move through this entire table. I have tried using focus
listeners, keyboard listeners, Focus Traversal policies, property
changes, and combinations between all of the above. I have taken out
my terrible attempts. Swing really should work without having to do
all this extra work but Java is what java is.
So if you are great at Java with swing please put away your mouse and run this
code and see if you can make the buttons activate without the mouse.
If you can and you can explain to me how to do it many blind users will
be in your debt.
Note that you should be able to Shift+Control+tab tot he table if the table is not the only control. On my sample it is. Then you should be able to arrow through the rows and columns and tab and shift+tab through the controls on the JPanel.
You can get the zip group of these files if you don't want to
put this all together yourself at this dropbox link:
https://www.dropbox.com/s/h4bdfu1mlo0jsvr/TableAccessTest.zip?dl=0
Here is the files. Each class has a comment with the file name before it. Again get the zip if you don't want to play block and copy.
//TableAccessTest.java
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
public class TableAccessTest extends JPanel
{
TableModel customRendererEditorTableModel = new TableModel();
JTable table;
public TableAccessTest()
{
setLayout(new BorderLayout());
table = new JTable(customRendererEditorTableModel);
table.setPreferredScrollableViewportSize(new Dimension(500, 600));
table.setRowSelectionAllowed(false);
table.setRowHeight(300);
table.getColumn("Custom JPanel").setCellRenderer(new CustomJPanelRenderer());
table.getColumn("Custom JPanel").setCellEditor(new CustomJPanelEditor());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Custom JPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new TableAccessTest();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
//CustomJPanel.java
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
public class CustomJPanel extends JPanel
{
JPanel colorPanel = new JPanel(new BorderLayout());
JButton jButton = new JButton("Change Color");
JSlider jSlider = new JSlider(JSlider.VERTICAL);
JTextField jTextField = new JTextField("");
public CustomJPanel()
{
jButton.setOpaque(true);
jButton.setFocusable(true);
jTextField.setEditable(false);
jTextField.setFocusable(true);
setFocusable(true);
jButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(4);
switch (randomInt)
{
case (0):
colorPanel.setBackground(Color.BLUE);
jTextField.setText("blue");
break;
case (1):
colorPanel.setBackground(Color.BLACK);
jTextField.setText("black");
break;
case (2):
colorPanel.setBackground(Color.CYAN);
jTextField.setText("cyan");
break;
default:
colorPanel.setBackground(Color.GREEN);
jTextField.setText("green");
break;
}
}
});
jSlider.setOpaque(true);
setLayout(new BorderLayout());
add(colorPanel, BorderLayout.CENTER);
add(jButton, BorderLayout.SOUTH);
add(jTextField, BorderLayout.NORTH);
add(jSlider, BorderLayout.EAST);
}
}
//TableModel.java
import javax.swing.table.AbstractTableModel;
public class TableModel extends AbstractTableModel
{
private String[] columnNames =
{
"First Column",
"Custom JPanel",
};
private Object[][] data =
{
{"Foo", new CustomJPanel()},
{"Bar", new CustomJPanel()}
};
public int getColumnCount()
{
return columnNames.length;
}
public int getRowCount()
{
return data.length;
}
public String getColumnName(int col)
{
return columnNames[col];
}
public Object getValueAt(int row, int col)
{
return data[row][col];
}
public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col)
{
return col >= 1;
}
public void setValueAt(Object value, int row, int col)
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
//CustomJPanelEditor.java
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
public class CustomJPanelEditor extends AbstractCellEditor implements TableCellEditor
{
CustomJPanel customJPanel;
public CustomJPanelEditor()
{
customJPanel = new CustomJPanel();
}
#Override
public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
customJPanel = (CustomJPanel) value;
return customJPanel;
}
#Override public Object getCellEditorValue()
{
return customJPanel;
}
}
//CustomJPanelRenderer.java
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class CustomJPanelRenderer implements TableCellRenderer
{
CustomJPanel rendererJPanel;
public CustomJPanelRenderer()
{
rendererJPanel = new CustomJPanel();
}
#Override
public java.awt.Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
rendererJPanel = (CustomJPanel) value;
return rendererJPanel;
}
}

How to modify javax.swing.TreeCellRenderer in order to stroke the text in the cell

Does anybody know how a javax.swing.TreeCellRenderer should be modified in order to stroke the text in the cell?
If you want to get stroked out text in some columns, you should use the renderer. If you need this font for all cells, you can simply modify the font of the table. Here is the example for both variants:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.font.TextAttribute;
import java.util.Collections;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("unchecked")
public class TableRendererTest {
public static void main(String[] args) {
JFrame frm = new JFrame("Renderer test");
DefaultTableModel model = new DefaultTableModel(new String[] {"First", "Second", "Third" }, 3);
model.setValueAt("Test String", 0, 0);
model.setValueAt("Corner String", 2, 0);
model.setValueAt("Last cell", 2, 2);
// table with strike-out renderer (first column is stroked out)
JTable tbl = new JTable(model);
tbl.getColumnModel().getColumn(0).setCellRenderer(new StrikeOutRenderer());
frm.add(new JScrollPane(tbl), BorderLayout.NORTH);
// table with strike-out font (all cells are stroked out)
JTable another = new JTable(model);
another.setFont(
another.getFont().deriveFont(Collections.singletonMap(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON)));
frm.add(new JScrollPane(another), BorderLayout.SOUTH);
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private static class StrikeOutRenderer extends DefaultTableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component res = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
res.setFont(res.getFont().deriveFont(Collections.singletonMap(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON)));
return res;
}
}
}

different font for combo box in Java

I would make a little rft text editor in Java and I would have that the different kind of fonts are show in my combo box in that font. The reason is because the user can see that font.
I know that you can use a combo box item for C#. But I didn't know for Java.
Can anyone help me?
Edit:
Sounds like you need to implement a custom renderer for your combo box.
See the java tutorial here: http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer
i.e. Something like this (assuming the Objects in your combo box are Fonts):
class CustomRenderer implements ListCellRenderer
{
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = new JLabel();
label.setFont(((Font) value).deriveFont(12f));
label.setText(((Font) value).getFontName());
return label;
}
}
Custom Combo box for font selection in java
Here is code :
package stack;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
public class CustomComboBox {
JComboBox fontComboBox;
JFrame frame;
String fontName[];
Integer array[];
public CustomComboBox() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
fontName = ge.getAvailableFontFamilyNames();
array = new Integer[fontName.length];
for(int i=1;i<=fontName.length;i++) {
array[i-1] = i;
}
fontComboBox = new JComboBox(array);
ComboBoxRenderar renderar = new ComboBoxRenderar();
fontComboBox.setRenderer(renderar);
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(fontComboBox);
frame.pack();
frame.setVisible(true);
}
public class ComboBoxRenderar extends JLabel implements ListCellRenderer {
#Override
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
int offset = ((Integer)value).intValue() - 1 ;
String name = fontName[offset];
setText(name);
setFont(new Font(name,Font.PLAIN,20));
return this;
}
}
public static void main(String args[]) {
new CustomComboBox();
}
}
and preview of the code see the Image
:

Cell renderer and the lost focus

I am using a JTable and in order to change the format of numbers. I have extended the DefaultTableRenderer class.
In the method getTableCellRenderedComponent, I retrun a new JLabel with the proper format.
My problem is by doing this the rectangle (border) that underlines the cell which has the focus has disappeared.
Is there a way to get the default border displayed whenever a cell has the focus with my custom render?
in order to change the format of numbers. I have extended the DefaultTableRenderer class.
Check out Table Format Renderers for an easier way to customize the renderer when all you need to do is format the data. That is you should override the setValue(...) method instead of the getTableCellRenderer(...) method.
If you use DefaultTableRenderer you can call super() method and get Border from returned component. Try next example:
import java.awt.Component;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class TestFrame extends JFrame {
public TestFrame() {
init();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private void init() {
JTable t = new JTable(3,3);
t.getColumnModel().getColumn(0).setCellRenderer(getRenderer());
add(new JScrollPane(t));
}
private TableCellRenderer getRenderer() {
return new DefaultTableCellRenderer(){
private JLabel l = new JLabel();
{
l.setOpaque(true);
}
#Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
JComponent tableCellRendererComponent = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus,row, column);
l.setText(value == null ? "" : value.toString());
l.setBorder(tableCellRendererComponent.getBorder());
l.setBackground(tableCellRendererComponent.getBackground());
l.setForeground(tableCellRendererComponent.getForeground());
return l;
}
};
}
public static void main(String... s){
new TestFrame();
}
}

JTable add/remove rows to custom table model (updating table display)

Does anyone have a good example of how to Add/Remove rows from a JTable using a custom table model? The issue I seem to be having is how to have the table keep updating when I add or remove items.
The real simple idea here is to have an add and remove button above my table which allows the user on the fly to change the table.
Here is example for adding row:
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
public class RowAdder extends JFrame {
final SimpleModel tableData = new SimpleModel();
JTable table = new JTable(tableData);
public static void main(String[] args) {
RowAdder ra = new RowAdder();
ra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ra.setSize(400, 300);
ra.setVisible(true);
}
public RowAdder() {
final JTextField textField = new JTextField();
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
tableData.addText(textField.getText());
textField.setText("");
}
});
add(textField, BorderLayout.SOUTH);
}
}
class SimpleModel extends AbstractTableModel {
Vector textData = new Vector();
public void addText(String text) {
textData.addElement(text);
fireTableDataChanged();
}
public int getRowCount() {
return textData.size();
}
public int getColumnCount() {
return 3;
}
public Object getValueAt(int row, int column) {
return textData.elementAt(row);
}
}
above ref from : http://www.java2s.com/Tutorial/Java/0240__Swing/AddrowstoaTable.htm
Checkout this tutorial about JTable:
http://download.oracle.com/javase/tutorial/uiswing/components/table.html
Specifically for table model check:
http://download.oracle.com/javase/tutorial/uiswing/components/table.html#data
I think this tutorial should answer all your question.
You have to notify the JTable object on changes of the underlying table model. The table is not observing the model but waiting for events.
After every change (or set of changes), create a TableModelEvent and call the tables tableChanged method.

Categories

Resources