これが私がやりたいことのスクリーンショットです:
そこで起こっていることは、JButtonが正しく表示されることですが、クリックしても何も起こりません。いくつかの検索の後、table.getValueAt()
によって返されるObject
はJButtonではなくStringであることがわかりました...
コードは次のとおりです。
tblResult = new JTable(data,cols) {
public TableCellRenderer getCellRenderer( int row, int column ) {
return new ClientsTableRenderer();
}
};
実行時にJTableを設定するためにこれを使用します:(tblResult
はClients.rblResult
)
SwingUtilities.invokeLater( new Runnable() {
public void run() {
DefaultTableModel aModel = new DefaultTableModel() {
//setting the jtable read only
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
String[] cols = {"N°","Société", "TVA", "CP", "Ville", ""};
aModel.setColumnIdentifiers(cols);
Object[] temp = new Object[6];
for(int i=0;i<result.length;i++) {
temp[0] = result[i].custNumber;
temp[1] = result[i].name;
temp[2] = result[i].tva;
temp[3] = result[i].cp;
temp[4] = result[i].city;
temp[5] = "Consulter";
aModel.addRow(temp);
}
Clients.tblResult.setModel(aModel);
Clients.tblResult.addMouseListener(new JTableButtonMouseListener(Clients.tblResult));
}}
);
ここでClientsTableRenderer
クラス
public class ClientsTableRenderer extends JPanel implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent( final JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setBackground(Color.WHITE);
if(column < 5) {
JLabel label = new JLabel(value.toString());
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER,0,9));
panel.setBackground(Color.WHITE);
panel.add(label);
this.add( panel);
} else {
JButton button = new JButton(value.toString());
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Clicked !");
}
});
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER,0,3));
panel.setBackground(Color.WHITE);
panel.add(button);
this.add(panel);
}
return this;
}
}
最後に、JTableButtonMouseListener():
public class JTableButtonMouseListener extends MouseAdapter {
private final JTable table;
public JTableButtonMouseListener(JTable table) {
this.table = table;
}
@Override public void mouseClicked(MouseEvent e) {
int column = table.getColumnModel().getColumnIndexAtX(e.getX());
int row = e.getY()/table.getRowHeight();
System.out.println("Col :"+column + "row:"+row);
if (row < table.getRowCount() && row >= 0 && column < table.getColumnCount() && column >= 0) {
Object value = table.getValueAt(row, column);
System.out.println("Value :"+value.getClass().getName());
if (value instanceof JButton) {
((JButton)value).doClick();
}
}
}
}
私はJavaに親切です。助けていただければ幸いです:)
前もって感謝します !
この Table Button Column Rob Camickがあなたのニーズに合うかもしれません。
問題は、テーブルにペイントされたときにJButton
がもはや存在しないことです。これらのコンポーネントは、テーブルがレンダリングされるときに「スタンプ」を作成するためにのみ使用されます。実際のボタンはありません。
ボタンをクリックする方法があり、まだテーブルを編集不可のままにしておきますですが、適切なコードとはほど遠いです。可能な解決策の簡単な概要(現時点では完全なコード例を示す時間はありません)
doClick
メソッド)をクリックします。そして、これはコードの汚い部分でさえありません。レンダラーは(できれば)毎回新しいJButton
を返さないので、ActionListener
にアタッチされているJButton
で、実際にクリックしたコンポーネントを追跡する必要があります。発生した。可能な解決策は、最後にJButton
を作成したテーブルモデル値への参照を保持することです(したがって、getCellRendererComponent
メソッドで行/列を追跡します)が、私はこれが最善のアプローチかどうか不明。
前述のとおり、可能な解決策ですが、エレガントとはほど遠いものです。
最も簡単な方法は、他の回答で指摘されているように、その1つの列を編集可能にし、エディターを使用することです
これを試して:
import Java.awt.Color;
import Java.awt.Component;
import Java.awt.EventQueue;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
public class TableWithButtonDemo
{
private JFrame frame = new JFrame("Table Demo");
private String[] columnNames = { "String", "Integer", "Float", "" };
private Object[][] data = { { "Dummy", new Integer(12), new Float(12.15), "Consulter" } };
private TableModel model = new DefaultTableModel(data, columnNames)
{
private static final long serialVersionUID = 1L;
public boolean isCellEditable(int row, int column)
{
return column == 3;
}
};
private JTable table = new JTable(model);
public TableWithButtonDemo()
{
table.getColumnModel().getColumn(3).setCellRenderer(new ClientsTableButtonRenderer());
table.getColumnModel().getColumn(3).setCellEditor(new ClientsTableRenderer(new JCheckBox()));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setShowHorizontalLines(true);
table.setShowVerticalLines(false);
JScrollPane scroll = new JScrollPane(table);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scroll);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
EventQueue.invokeLater(new Runnable()
{
public void run()
{
new TableWithButtonDemo();
}
});
}
class ClientsTableButtonRenderer extends JButton implements TableCellRenderer
{
public ClientsTableButtonRenderer()
{
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
setForeground(Color.black);
setBackground(UIManager.getColor("Button.background"));
setText((value == null) ? "" : value.toString());
return this;
}
}
public class ClientsTableRenderer extends DefaultCellEditor
{
private JButton button;
private String label;
private boolean clicked;
private int row, col;
private JTable table;
public ClientsTableRenderer(JCheckBox checkBox)
{
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
fireEditingStopped();
}
});
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
this.table = table;
this.row = row;
this.col = column;
button.setForeground(Color.black);
button.setBackground(UIManager.getColor("Button.background"));
label = (value == null) ? "" : value.toString();
button.setText(label);
clicked = true;
return button;
}
public Object getCellEditorValue()
{
if (clicked)
{
JOptionPane.showMessageDialog(button, "Column with Value: "+table.getValueAt(row, 1) + " - Clicked!");
}
clicked = false;
return new String(label);
}
public boolean stopCellEditing()
{
clicked = false;
return super.stopCellEditing();
}
protected void fireEditingStopped()
{
super.fireEditingStopped();
}
}
}
この記事では、実際にボタンをクリックしたかどうかに関係なく、MouseListenersを追加して計算することなく、問題に対するより簡単なアプローチを提供します。
テーブルモデルをオーバーロードし、ボタンのあるセルに対してisCellEditable(int、int)がfalseを返すように設定します。
テーブルに追加されたMouseListenerでうまく機能します。
ここに私の解決策があります
ButtonEditor.Java
public abstract class ButtonEditor extends DefaultCellEditor implements ActionListener {
private static final long serialVersionUID = 1L;
/** The cell's row. */
protected int row;
/** The cell's column. */
protected int column;
/** The cell's column. */
protected JTable table;
/** The button we are editing. */
protected JButton button;
/** The panel used when editing. */
protected JPanel panel = new JPanel(new GridBagLayout());
/** Constructor */
public ButtonEditor() {super(new JCheckBox());}
/**
* This method is called when the user try to modify a cell.
* In this case it will be called whenever the user click on the cell.
* @param table
* @param value
* @param isSelected
* @param row
* @param column
* @return JPanel The JPanel returned contains a JButton with an ActionListener.
*/
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
this.row = row;
this.column = column;
this.table = table;
button = (JButton) value;
//prevent to add the action listener everytime the user click on the cell.
if(button.getActionListeners().length == 0) button.addActionListener(this);
panel.add(button);
panel.setBackground(table.getGridColor());
return panel;
}
/**
* Return a renderer for JButtons. The result is a button centered in the table's cell.
* @return
*/
public static TableCellRenderer getRenderer() {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JPanel panel = new JPanel(new GridBagLayout());
panel.add((JButton) value);
panel.setBackground(table.getGridColor());
return panel;
}
};
}
}
そして、それを使用する方法は次のとおりです。
Demo.Java
table.setDefaultRenderer(JButton.class, ButtonEditor.getRenderer());
table.setDefaultEditor(JButton.class, new ButtonEditor() {
@Override
public void actionPerformed(ActionEvent e) {
//handle clicks here. for example:
if(column == 5) {
System.out.Println(row);
button.setFocusPainted(false);
}
}
});