This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Accessing a JTextField in JTableHeader
How to make JTableHeader as editable. F.e. i make ColumnHeader as JTextField. What must i do to make JTextField editable. See the example:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.event.*;
public class Test extends JFrame {
String[][] cellValues = { { "v00", "v01", "v02" }, { "v10", "v11", "v12" },
{ "v20", "v21", "v22" }, { "v30", "v31", "v32" },
{ "v40", "v41", "v42" }, { "v50", "v51", "v52" } };
String[] columnNames = { "v00", "v01", "v02" };
javax.swing.JTable jTable1 = new javax.swing.JTable(cellValues, columnNames);
public Test() {
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
this.getContentPane().add(new JScrollPane(jTable1), null);
for (int i = 0; i < 3; i++)
jTable1.getColumnModel().getColumn(i)
.setHeaderRenderer(new Renderer());
}
public static void main(String[] args) {
Test frame = new Test();
frame.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
}
class Renderer extends JPanel implements TableCellRenderer {
JLabel label = new JLabel(" ");
JTextField field = new JTextField("%");
public Renderer() {
super(new BorderLayout());
add(label, BorderLayout.NORTH);
add(field, BorderLayout.CENTER);
setBorder(BorderFactory.createEtchedBorder());
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
label.setText(value.toString());
return (JComponent) this;
}
public String toString() {
return label.toString();
}
public void setText(String text) {
label.setText(text);
}
}
Here's a simple approach for making editable headers (no custom renderers or UIs required):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class JTableEditableHeaderDemo implements Runnable
{
private JTable table;
private JTableHeader header;
private JPopupMenu renamePopup;
private JTextField text;
private TableColumn column;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new JTableEditableHeaderDemo());
}
public JTableEditableHeaderDemo()
{
table = new JTable(10, 5);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
header = table.getTableHeader();
header.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent event)
{
if (event.getClickCount() == 2)
{
editColumnAt(event.getPoint());
}
}
});
text = new JTextField();
text.setBorder(null);
text.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
renameColumn();
}
});
renamePopup = new JPopupMenu();
renamePopup.setBorder(new MatteBorder(0, 1, 1, 1, Color.DARK_GRAY));
renamePopup.add(text);
}
public void run()
{
JFrame f = new JFrame("Double-click header to edit");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(table));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private void editColumnAt(Point p)
{
int columnIndex = header.columnAtPoint(p);
if (columnIndex != -1)
{
column = header.getColumnModel().getColumn(columnIndex);
Rectangle columnRectangle = header.getHeaderRect(columnIndex);
text.setText(column.getHeaderValue().toString());
renamePopup.setPreferredSize(
new Dimension(columnRectangle.width, columnRectangle.height - 1));
renamePopup.show(header, columnRectangle.x, 0);
text.requestFocusInWindow();
text.selectAll();
}
}
private void renameColumn()
{
column.setHeaderValue(text.getText());
renamePopup.setVisible(false);
header.repaint();
}
}
There is a complete solution under the following link, looks quite good at the first sight!
How do I create a JTable with editable headers?
Related
I am performing actions for 2 combo boxes which involves in changing the background color of JLabel. Here is my code,
public class JavaApplication8 {
private JFrame mainFrame;
private JLabel signal1;
private JLabel signal2;
private JPanel s1Panel;
private JPanel s2Panel;
public JavaApplication8()
{
try {
prepareGUI();
} catch (ClassNotFoundException ex) {
Logger.getLogger(JavaApplication8.class.getName())
.log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws
ClassNotFoundException
{
JavaApplication8 swingControl = new JavaApplication8();
swingControl.showCombobox1();
}
public void prepareGUI() throws ClassNotFoundException
{
mainFrame = new JFrame("Signal");
mainFrame.setSize(300,200);
mainFrame.setLayout(new GridLayout(3, 0));
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
signal1 = new JLabel("Signal 1",JLabel.LEFT);
signal1.setSize(100,100);
signal1.setOpaque(true);
signal2 = new JLabel("Signal 2",JLabel.LEFT);
signal2.setSize(100,100);
signal2.setOpaque(true);
final DefaultComboBoxModel light = new DefaultComboBoxModel();
light.addElement("Red");
light.addElement("Green");
final JComboBox s1Combo = new JComboBox(light);
s1Combo.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae)
{
if(s1Combo.getSelectedIndex() == 0)
{
signal1.setBackground(Color.RED);
}
else
{
signal1.setBackground(Color.GREEN);
}
}
});
final JComboBox s2Combo1 = new JComboBox(light);
s2Combo1.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae)
{
if(s2Combo1.getSelectedIndex() == 0)
{
signal2.setBackground(Color.RED);
}
else
{
signal2.setBackground(Color.GREEN);
}
}
});
s1Panel = new JPanel();
s1Panel.setLayout(new FlowLayout());
JScrollPane ListScrollPane = new JScrollPane(s1Combo);
s1Panel.add(signal1);
s1Panel.add(ListScrollPane);
s2Panel = new JPanel();
s2Panel.setLayout(new FlowLayout());
JScrollPane List1ScrollPane = new JScrollPane(s2Combo1);
s2Panel.add(signal2);
s2Panel.add(List1ScrollPane);
mainFrame.add(s1Panel);
mainFrame.add(s2Panel);
String[] columnNames = {"Signal 1","Signal 2"};
Object[][] data = {{"1","1"}};
final JTable table = new JTable(data,columnNames);
JScrollPane tablepane = new JScrollPane(table);
table.setFillsViewportHeight(true);
mainFrame.add(tablepane);
mainFrame.setVisible(true);
}
}
When Executed, If I change the item from combo box 1, the 2nd combo box also performs the change. Where did I go wrong?
Yours is a simple solution: don't have the JComboBoxes share the same model. If they share the same model, then changes to the selected item of one JComboBox causes a change in the shared model which changes the view of both JComboBoxes.
I wold use a method to create your combo-jlabel duo so as not to duplicate code. For instance:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class App8 extends JPanel {
private static final int COMBO_COUNT = 2;
private static final String SIGNAL = "Signal";
private List<JComboBox<ComboColor>> comboList = new ArrayList<>();
public App8() {
setLayout(new GridLayout(0, 1));
for (int i = 0; i < COMBO_COUNT; i++) {
DefaultComboBoxModel<ComboColor> cModel = new DefaultComboBoxModel<>(ComboColor.values());
JComboBox<ComboColor> combo = new JComboBox<>(cModel);
add(createComboLabelPanel((i + 1), combo));
comboList.add(combo);
}
}
private JPanel createComboLabelPanel(int index, final JComboBox<ComboColor> combo) {
JPanel panel = new JPanel();
final JLabel label = new JLabel(SIGNAL + " " + index);
label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
label.setOpaque(true);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
ComboColor cColor = (ComboColor) combo.getSelectedItem();
label.setBackground(cColor.getColor());
}
});
panel.add(label);
panel.add(combo);
return panel;
}
private static void createAndShowGui() {
App8 mainPanel = new App8();
JFrame frame = new JFrame("App8");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum ComboColor {
RED("Red", Color.RED),
GREEN("Green", Color.GREEN);
private String text;
private Color color;
public String getText() {
return text;
}
public Color getColor() {
return color;
}
private ComboColor(String text, Color color) {
this.text = text;
this.color = color;
}
#Override
public String toString() {
return text;
}
}
how can I refresh the highlighter in my JTable after changing the search value in the JTextField? It works fine with the JTextArea under the JTextfield, but I the JTable won't refresh the highlighter. Any Suggestions??
This is my Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
import javax.swing.text.DefaultHighlighter.DefaultHighlightPainter;
public class BeispielTabelle {
JTextField field;
JTextArea textFeld = new JTextArea("Hello World!");
String input="Stefan";
//Titel der Tabelle
String[] title = {"EINS", "ZWEI", "DREI"};
//Tabellendaten
Object[][] playerdata = {
{"34", "Stefan", "Mein Name ist Stefan"},
{"32", "Dirk", "Ich bin der Dirk"},
{"99", "Patrick", "Ich heisse Patrick"},
{"100", "Anna", "Ich bin die Anna"},};
//TableModel
DefaultTableModel model = new DefaultTableModel(playerdata,title);
//Tabelle erstellen
JTable textTable = new JTable(model);
public JPanel erstelleTabelle() {
JPanel totalGUI = new JPanel();
//CellRenderer
SearchRenderer cellRenderer = new SearchRenderer();
//Spaltenbreiten festlegen
textTable.setDefaultRenderer(String.class, cellRenderer);
textTable.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
textTable.getColumnModel().getColumn(1).setCellRenderer(cellRenderer);
textTable.getColumnModel().getColumn(2).setCellRenderer(cellRenderer);
textTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // Autoresizing abschalten, sonst sind alle Spalten gleich breit:
textTable.getColumnModel().getColumn(0).setPreferredWidth(60);
textTable.getColumnModel().getColumn(1).setPreferredWidth(60);
textTable.getColumnModel().getColumn(2).setPreferredWidth(180);
//das Ganze scrollbar machen
JScrollPane scrollPane = new JScrollPane(textTable);
//TextFeld erstellen
field = new JTextField();
field.addActionListener(new ActionListener () {
#Override
public void actionPerformed(ActionEvent e) {
input = field.getText();
System.out.println(input);
//updateRowHeights();
highlightText();
}
});
totalGUI.add(scrollPane);
totalGUI.add(field);
totalGUI.add(textFeld);
return totalGUI;
}
void highlightText() {
DefaultHighlightPainter yellowPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
Highlighter highlighter = textFeld.getHighlighter();
highlighter.removeAllHighlights();
String text = textFeld.getText();
String pattern = input;
int index = text.indexOf(pattern);
while ( index >= 0 ) {
int len = pattern.length();
try {
highlighter.addHighlight(index, index+len, yellowPainter);
} catch (BadLocationException e) {
e.printStackTrace();
}
index = text.indexOf(pattern, index+len);
}
}
private static void createAndShowGUI() {
//create main frame
JFrame mainFrame = new JFrame("");
BeispielTabelle test = new BeispielTabelle();
JPanel totalGUI = new JPanel();
totalGUI = test.erstelleTabelle();
totalGUI.setLayout(new BoxLayout(totalGUI, BoxLayout.Y_AXIS));
//visible mode
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.add(totalGUI); //integrate main panel to main frame
mainFrame.pack();
mainFrame.setVisible(true);
}
public static void main (String[] args) {
createAndShowGUI();
}//main
}//GUI_main
And this is my SearchRenderer
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.BadLocationException;
import java.awt.*;
public class SearchRenderer extends JTextArea implements TableCellRenderer {
/**
*
*/
private static final long serialVersionUID = 1L;
public SearchRenderer() {}//constructor
BeispielTabelle tabelle = new BeispielTabelle();
String textForSearch=tabelle.input;
#Override
public Component getTableCellRendererComponent (JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column ) {
this.setText((String) value);
if(value != null) {
String string = value.toString();
if(string.contains(textForSearch)){
int indexOf = string.indexOf(textForSearch);
while(indexOf >=0) {
try {
this.getHighlighter().addHighlight(indexOf,indexOf+textForSearch.length(),new javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.GREEN));
} catch (BadLocationException e) {
e.printStackTrace();
}
indexOf = string.indexOf(textForSearch, indexOf+textForSearch.length());
}
}
} else {
this.setText("");
this.getHighlighter().removeAllHighlights();
}
return this;
}
}
Maybe you can use JTable#repaint()
import java.awt.*;
import java.util.Objects;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.text.*;
public final class SearchRendererTest {
private final JTextField field = new JTextField("Stefan");
private final SearchRenderer renderer = new SearchRenderer();
//Titel der Tabelle
private final String[] title = {"EINS", "ZWEI", "DREI"};
//Tabellendaten
private final Object[][] playerdata = {
{"34", "Stefan", "Mein Name ist Stefan"},
{"32", "Dirk", "Ich bin der Dirk"},
{"99", "Patrick", "Ich heisse Patrick"},
{"100", "Anna", "Ich bin die Anna"},
};
private final TableModel model = new DefaultTableModel(playerdata, title);
private final JTable table = new JTable(model);
public JComponent makeUI() {
table.setDefaultRenderer(Object.class, renderer);
field.getDocument().addDocumentListener(new DocumentListener() {
#Override public void insertUpdate(DocumentEvent e) {
fireDocumentChangeEvent();
}
#Override public void removeUpdate(DocumentEvent e) {
fireDocumentChangeEvent();
}
#Override public void changedUpdate(DocumentEvent e) {
/* not needed */
}
});
fireDocumentChangeEvent();
JPanel sp = new JPanel(new BorderLayout(5, 5));
sp.add(new JLabel("regex pattern:"), BorderLayout.WEST);
sp.add(field);
sp.add(Box.createVerticalStrut(2), BorderLayout.SOUTH);
sp.setBorder(BorderFactory.createTitledBorder("Search"));
JPanel p = new JPanel(new BorderLayout(5, 5));
p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
p.add(sp, BorderLayout.NORTH);
p.add(new JScrollPane(table));
return p;
}
private void fireDocumentChangeEvent() {
String pattern = field.getText().trim();
renderer.setPattern(pattern);
table.repaint();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SearchRendererTest().makeUI());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class SearchRenderer implements TableCellRenderer {
private static final Color BACKGROUND_SELECTION_COLOR = new Color(220, 240, 255);
private final transient Highlighter.HighlightPainter highlightPainter
= new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
private final JTextField field = new JTextField();
private String pattern = "";
private String prev;
public boolean setPattern(String str) {
if (str == null || str.equals(pattern)) {
return false;
} else {
prev = pattern;
pattern = str;
return true;
}
}
public SearchRenderer() {
super();
field.setOpaque(true);
field.setBorder(BorderFactory.createEmptyBorder());
field.setForeground(Color.BLACK);
field.setBackground(Color.WHITE);
field.setEditable(false);
}
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
String txt = Objects.toString(value, "");
Highlighter highlighter = field.getHighlighter();
highlighter.removeAllHighlights();
field.setText(txt);
field.setBackground(isSelected ? BACKGROUND_SELECTION_COLOR : Color.WHITE);
if (pattern != null && !pattern.isEmpty() && !pattern.equals(prev)) {
Matcher matcher = Pattern.compile(pattern).matcher(txt);
if (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
try {
highlighter.addHighlight(start, end, highlightPainter);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
return field;
}
}
i got stuck at adding a button to a JComboBox editor, I succeeded to add a button but I got some issues like when I first enter to the editor an action perform event gets fired which is unacceptable and the other is I can't get the text typed.
Result:
Problems:
#Override
public Component getEditorComponent() {
return panel;
}
This is the problem, if I return panel.jtexfield I only get a text field without a button, so what's the trick here?
Here is my code
import Store.util.DatabaseHelper;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import org.hibernate.HibernateException;
import org.netbeans.lib.awtextra.AbsoluteLayout;
public class NewComboTest extends JFrame {
private ArrayList<Object> shopCart = new ArrayList<Object>();
private JComboBox cb;
private static final Object[] comboContents = {
"First", "Second", "Third", "Fourth", "Fifth"
};
public NewComboTest() {
super("New Combo Test");
setLayout(null);
cb = new JComboBox();
cb.setRenderer(new NewComboRenderer());
cb.setEditor(new NewComboEditor());
cb.setEditable(true);
cb.setSize(new Dimension(350, 100));
for (int i = 0; i < comboContents.length; i++) {
cb.addItem(comboContents[ i]);
}
cb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("_____________" + cb.getSelectedItem());
shopCart.add(cb.getSelectedItem());
System.out.println("items added" + shopCart);
}
});
cb.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
System.out.println("KeyReleased" + cb.getEditor().getItem().toString());
populateModel(cb.getEditor().getItem().toString());
}
});
getContentPane().add(cb, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 200, 480, 50));
setSize(1200, 450);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] arg) {
new NewComboTest();
}
private class NewComboEditor extends JPanel implements ComboBoxEditor {
JTextField tf;
JButton eraseButton;
textPanel panel = new textPanel();
public NewComboEditor() {
}
#Override
public void addActionListener(ActionListener l) {
tf.addActionListener(l);
}
#Override
public Component getEditorComponent() {
return panel;
}
public Component getEditorComponent2() {
return panel;
}
#Override
public Object getItem() {
return tf.getText();
}
#Override
public void removeActionListener(ActionListener l) {
tf.removeActionListener(l);
}
#Override
public void selectAll() {
tf.selectAll();
}
#Override
public void setItem(Object o) {
if (o != null) {
tf.setText(tf.getText());
} else {
tf.setText("");
}
}
private class textPanel extends JPanel {
JTextField jTextField1 = new JTextField();
JButton jButton1 = new JButton();
public textPanel() {
setLayout(new BorderLayout());
jButton1.setBackground(new java.awt.Color(255, 255, 255));
jButton1.setForeground(new java.awt.Color(0, 51, 51));
jButton1.setText("X");
jButton1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jTextField1.setText("");
}
});
add(jTextField1, BorderLayout.CENTER);
add(jButton1, BorderLayout.EAST);
}
public String getText(){
return jTextField1.getText();
}
}
}
private class NewComboRenderer extends JLabel implements ListCellRenderer {
public NewComboRenderer() {
setOpaque(true);
}
public Component getListCellRendererComponent(
JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText(value.toString());
setBackground(isSelected ? Color.BLUE : Color.white);
setForeground(isSelected ? Color.white : Color.red);
return this;
}
}
/* public void populateModel(String text) throws HibernateException {
java.util.List l = DatabaseHelper.GetProductsBy(text);
for (Object object : l) {
cb.addItem(object);
}
ignore this its unnecessary.
*/
}
}
I also wish to set the text font and size to the same as the set up at the combo box.
The first set of problems I can see is, you define a JTextField and JButton in the NewComboEditor, but also define a textPanel, which contains all these things any way. But instead of using the components on the textPane, you use the newly created components (in the NewComboEditor) instead...In fact, I'm not even sure how that could work, because you never initilise these components (in the NewComboEditor), so there should be a NullPointerException...
If that wasn't enough problems, the JTextField and JButton aren't added to anything anyway...
Instead...
NewComboEditor shouldn't need to extend from anything (or it could extend from textPane instead if you really wanted to).
All references to the field should be made to the text field in the textPane
As an example...
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import javax.swing.ComboBoxEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CustomComboBoxEditor {
public static void main(String[] args) {
new CustomComboBoxEditor();
}
public CustomComboBoxEditor() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JComboBox cb = new JComboBox();
cb.addItem("Apple");
cb.addItem("Banana");
cb.addItem("Orange");
cb.setEditable(true);
cb.setEditor(new MyComboBoxEditor());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(cb);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MyComboBoxEditor implements ComboBoxEditor {
private EditorPane editorPane;
public MyComboBoxEditor() {
editorPane = new EditorPane();
}
#Override
public Component getEditorComponent() {
return editorPane;
}
#Override
public void setItem(Object anObject) {
editorPane.setText(anObject == null ? null : anObject.toString());
}
#Override
public Object getItem() {
return editorPane.getText();
}
#Override
public void selectAll() {
editorPane.selectAll();
}
#Override
public void addActionListener(ActionListener l) {
editorPane.addActionListener(l);
}
#Override
public void removeActionListener(ActionListener l) {
editorPane.removeActionListener(l);
}
}
public class EditorPane extends JPanel {
private JTextField field;
private JButton button;
public EditorPane() {
field = new JTextField(10);
button = new JButton("X");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
add(field, gbc);
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.gridx++;
add(button, gbc);
}
#Override
public void addNotify() {
super.addNotify();
field.requestFocusInWindow();
}
public void selectAll() {
field.selectAll();
}
public void setText(String text) {
field.setText(text);
}
public String getText() {
return field.getText();
}
public void addActionListener(ActionListener listener) {
field.addActionListener(listener);
}
public void removeActionListener(ActionListener listener) {
field.removeActionListener(listener);
}
}
}
Now, if you want to set the field's properties to be the same as the combo box, I would simply pass a reference of the combo box to the editor and allow it to extract the properties you need (i.e. font, color, etc.)
There are a lot of time, that I'm trying to make the Cell Renderer in the JavaOne 2007's talk maked by Shanon Hickey, Romain Guy and Chris Campbell, in the pages 38 and 39 (that you can find here : http://docs.huihoo.com/javaone/2007/desktop/TS-3548.pdf).
I asked Romain Guy, and Chris campbell, but without success, they say that they cannot pulish the source code.
So, any one can, give an idea, or even a source code on how to make this complex cell renderer ?
I learned this slides of many times, they say :
1)Cell Renderer: Column Spanning
Viewport clips column contents
and
2) Viewport moves to
expose the right text
for each column
I don't understand that, please can you give more in depth explanations ?
Cheers
Windows 7
JDK 1.7.0_21
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class ComplexCellRendererTest {
private static boolean DEBUG = true;
private JRadioButton r1 = new JRadioButton("scrollRectToVisible");
private JRadioButton r2 = new JRadioButton("setViewPosition");
public JComponent makeUI() {
String[] columnNames = {"AAA", "BBB"};
Object[][] data = {
{new Test("1", "aaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), "4"},
{new Test("2", "1234567890\nabcdefghijklmdopqrstuvwxyz"), "5"},
{new Test("3", "ccccccccccccccccccccccccccccccccccc\ndddddddddddd"), "6"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
#Override public boolean isCellEditable(int row, int column) {
return false;
}
};
final JTable table = new JTable(model);
table.getTableHeader().setReorderingAllowed(false);
table.setRowSelectionAllowed(true);
table.setFillsViewportHeight(true);
table.setShowVerticalLines(false);
table.setIntercellSpacing(new Dimension(0,1));
table.setRowHeight(56);
for(int i=0; i<table.getColumnModel().getColumnCount(); i++) {
TableColumn c = table.getColumnModel().getColumn(i);
c.setCellRenderer(new ComplexCellRenderer());
c.setMinWidth(50);
}
ActionListener al = new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
DEBUG = (e.getSource()==r1);
table.repaint();
}
};
Box box = Box.createHorizontalBox();
ButtonGroup bg = new ButtonGroup();
box.add(r1); bg.add(r1); r1.addActionListener(al);
box.add(r2); bg.add(r2); r2.addActionListener(al);
r1.setSelected(true);
JPanel p = new JPanel(new BorderLayout());
p.add(box, BorderLayout.NORTH);
p.add(new JScrollPane(table));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new ComplexCellRendererTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
static class ComplexCellRenderer extends JPanel implements TableCellRenderer {
private final JTextArea textArea = new JTextArea(2, 999999);
private final JLabel label = new JLabel();
private final JScrollPane scroll = new JScrollPane();
public ComplexCellRenderer() {
super(new BorderLayout(0,0));
scroll.setViewportView(textArea);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setViewportBorder(BorderFactory.createEmptyBorder());
scroll.setOpaque(false);
scroll.getViewport().setOpaque(false);
textArea.setBorder(BorderFactory.createEmptyBorder());
//textArea.setMargin(new Insets(0,0,0,0));
textArea.setForeground(Color.RED);
textArea.setOpaque(false);
label.setBorder(BorderFactory.createMatteBorder(0,0,1,1,Color.GRAY));
setBackground(Color.WHITE);
setOpaque(true);
add(label, BorderLayout.NORTH);
add(scroll);
}
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
Test test;
if(value instanceof Test) {
test = (Test)value;
} else {
String title = value.toString();
Test t = (Test)table.getModel().getValueAt(row, 0);
test = new Test(title, t.text);
}
label.setText(test.title);
textArea.setText(test.text);
Rectangle cr = table.getCellRect(row, column, false);
if(DEBUG) {
//Unexplained flickering on first row?
textArea.scrollRectToVisible(cr);
} else {
//Work fine for me (JDK 1.7.0_21, Windows 7 64bit):
scroll.getViewport().setViewPosition(cr.getLocation());
}
if(isSelected) {
setBackground(Color.ORANGE);
} else {
setBackground(Color.WHITE);
}
return this;
}
}
}
class Test {
public final String title;
public final String text;
//public final Icon icon;
public Test(String title, String text) {
this.title = title;
this.text = text;
}
}
I am creating a program to work like Microsoft Excel, in JAVA. My problem is how do I put the row numbers beside each row of the JTable? I have seen it working in other Java Programs - I just can not figure out how to include it in mine. Google gave me this website, and apparently it works. When I use it in my program this nothing happen. :/
I there a better way of adding row numbers in a JTable?
I have looked at the Java Tutorials already.
I am sorry if this question has been asked before.
There exists simple solution for that, and looks like as #camickr is more complex, (by Walter or Darryl from forums.sun.com)
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.UIManager.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TestTableRowTable {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if (info.getName().equals("Nimbus")) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
e1.printStackTrace();
}
final JTable table = new JTable(10, 6);
for (int i = 0; i < table.getRowCount(); i++) {
table.setValueAt(i, i, 0);
}
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
table.setRowSorter(sorter);
final AbstractTableModel model = new AbstractTableModel() {
private static final long serialVersionUID = 1L;
#Override
public int getColumnCount() {
return 1;
}
#Override
public Object getValueAt(int row, int column) {
return table.convertRowIndexToModel(row);
}
#Override
public int getRowCount() {
return table.getRowCount();
}
};
JTable headerTable = new JTable(model);
headerTable.setShowGrid(false);
headerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
headerTable.setPreferredScrollableViewportSize(new Dimension(30, 0));
headerTable.getColumnModel().getColumn(0).setPreferredWidth(30);
headerTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable x, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
boolean selected = table.getSelectionModel().isSelectedIndex(row);
Component component = table.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table, value, false, false, -1, -2);
((JLabel) component).setHorizontalAlignment(JLabel.CENTER);
if (selected) {
component.setFont(component.getFont().deriveFont(Font.BOLD));
} else {
component.setFont(component.getFont().deriveFont(Font.PLAIN));
}
return component;
}
});
table.getRowSorter().addRowSorterListener(new RowSorterListener() {
#Override
public void sorterChanged(RowSorterEvent e) {
model.fireTableDataChanged();
}
});
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
model.fireTableRowsUpdated(0, model.getRowCount() - 1);
}
});
JScrollPane pane = new JScrollPane(table);
pane.setRowHeaderView(headerTable);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(pane);
frame.getContentPane().add(new JButton(new AbstractAction("Toggle filter") {
private static final long serialVersionUID = 1L;
private RowFilter<TableModel, Object> filter = new RowFilter<TableModel, Object>() {
#Override
public boolean include(javax.swing.RowFilter.Entry<? extends TableModel, ? extends Object> entry) {
return ((Number) entry.getValue(0)).intValue() % 2 == 0;
//return ((String) entry.getValue(0)).length()>0 ;
//return ((Date) entry.getValue(0)).getTime()< ;
}
};
#Override
public void actionPerformed(ActionEvent e) {
if (sorter.getRowFilter() != null) {
sorter.setRowFilter(null);
} else {
sorter.setRowFilter(filter);
}
}
}), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private TestTableRowTable() {
}
}