私は基本的に何かをコピーしています。ユーザーがJTableにデータを入力すると、そのデータが解析され、処理され、適切なタイプのCell(これは複数のサブクラスを作成したインターフェイス)のtoString()メソッドが表示されます。代替のtoString()を表示するカスタムセルエディタを使用したメソッド
ユーザーがFormulaCellの編集を開始したとき、toString()メソッドで取得した評価式ではなく、getFormula()メソッドで取得した式をセルに表示します。
私はカスタムセルエディタを調べましたが、どのメソッドをオーバーライドするかわかりませんでした。私は、コードは、カスタムセルエディタまたはものは何でも私が作る必要があるのこの内部のようなものになるだろうと思う:
if (cell instanceof FormulaCell) {
startingText = (FormulaCell) cell).getFormula();
}
JTableの中の各セルは別のクラスを持っているので、私は本当にのDefaultTableModelののgetColumnClass()メソッドをオーバーライドすることはできません数式セルクラス用のカスタムセルエディタを設定します。希望の動作を作成する方法上の任意の案内が高く評価されるだろう
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import cell.*;
public class Program extends JPanel {
private DefaultTableModel model;
private JTable table;
public static final int ASCII_SHIFT = 64, HEIGHT = 10, WIDTH = 7, ROW_HEIGHT = 40;
public static final Dimension BUTTON_SIZE = new Dimension(70,30),
TABLE_SIZE = new Dimension(780, 400);
//makes program runnable
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
//sets title and does everything necessary to
//create and show the GUI
JFrame frame = new JFrame("TextExcel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Program contentPane = new Program();
contentPane.setOpaque(true);
frame.setContentPane(contentPane);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
public Program() {
//sets the layout
super(new BorderLayout());
//creates a String[] for column headers
String[] letter = new String[WIDTH];
for (int i = 0; i < letter.length; i++) {
byte[] character = {(byte) (i + ASCII_SHIFT + 1)};
letter[i] = new String(character);
}
//creates the table
model = new DefaultTableModel(letter, HEIGHT);
table = new JTable(model);
//makes a cell parse the input when enter is pressed
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
TableCellListener tcl = (TableCellListener)e.getSource();
int row = tcl.getRow();
int column = tcl.getColumn();
String input = (String) model.getValueAt(row, column);
parse(input, row, column);
}
};
@SuppressWarnings("unused")
TableCellListener tcl = new TableCellListener(table, action);
//centers the headers
JTableHeader header = table.getTableHeader();
header.setDefaultRenderer(new HeaderRenderer(table));
header.setReorderingAllowed(false);
//centers text in cells
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
table.setDefaultRenderer(Object.class, centerRenderer);
//sets the height of rows
for (int i = 0; i < HEIGHT; i++) {
table.setRowHeight(i, ROW_HEIGHT);
}
//creates a scroll-pane for the table and numbers the rows
JScrollPane scrollPane = new JScrollPane(table);
JTable rowTable = new RowNumberTable(table);
scrollPane.setRowHeaderView(rowTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());
add(scrollPane);
//sizes the table
table.setFillsViewportHeight(true);
table.setPreferredScrollableViewportSize(TABLE_SIZE);
//creates a panel to place buttons
JPanel buttonPanel = new JPanel(new FlowLayout());
//creates a button to clear the table
JButton clearButton = new JButton("clear");
clearButton.setPreferredSize(BUTTON_SIZE);
clearButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
clearTable();
}
});
buttonPanel.add(clearButton);
//message displayed when help button is pressed
String helpMessage = "To construct a Cell, double click a cell, "
+ "enter the argument, and press enter.\n"
+ "To clear a Cell, press the \"clear\" button.\n\n"
+ "There are 5 subclasses of Cell:\n"
+ "StringCell, DateCell, NumberCell, "
+ "FormulaCell, and SumAvgCell.\n"
+ "All numbers are displayed as Fractions and all Cells displaying numbers extend\n"
+ "NumberCell. Any double entered will be converted to a Fraction.\n\n"
+ "* StringCells display text and are simply typed into the cell. If an input is\n"
+ "invalid for all other types of Cell, it will become a StringCell.\n"
+ "* DateCells display dates in the form (Month Day, Year). They are constructed\n"
+ "in the form (m/d/yy) or (m/d/yyyy). Extra zeroes in m and d are not necessary.\n"
+ "* NumberCells simply display Fractions and can be constructed from a double,\n"
+ "int, standard fraction, or mixed fraction.\n"
+ "* FormulaCells are constructed from any combination of operations(+-*/%),\n"
+ "values, parantheses, and references. Order of operations is supported. An\n"
+ "example of a valid input would be \"(A1 + 4.4 * b3) % C2 - 3_6/8\".\n"
+ "* SumAvgCells can be used to find the sum or average of a rectangular area of\n"
+ "cells. They are constructed in the form (command reference - reference).\n"
+ "The first reference is the top-left corner and the second reference is the\n"
+ "bottom-right corner. An example of a valid input would be \"sum A1 - B2\".\n"
+ "Another valid input would be \"avg C1 - C8\".";
//creates a help button to display a helpful message
JButton helpButton = new JButton("help");
helpButton.setPreferredSize(BUTTON_SIZE);
helpButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(getComponent(0), helpMessage, "HelpBox", 1);
}
});
buttonPanel.add(helpButton);
//creates a panel to place the table
JPanel tablePanel = new JPanel(new BorderLayout());
tablePanel.add(scrollPane, BorderLayout.CENTER);
//adds the button and table panels
add(tablePanel, BorderLayout.NORTH);
add(buttonPanel, BorderLayout.SOUTH);
}
//parses user input to set a cell value
public void parse(String input, int row, int column) {
//initializes cell to be set
Cell cell = null;
//helpful variables
String ref = "([a-g]\\d*)";
String dub = "([-+]?\\d*\\.?\\d*)";
String frac = "((\\d+_\\d+/\\d+)|(\\d+/\\d+))";
//parses the input according to regular expressions
input = input.toLowerCase();
if (input.matches("(" + ref + "|" + dub + "|" + frac + ")"
+ "([-+*/%] (" + ref + "|" + dub + "|" + frac + "))+")) {
cell = new FormulaCell(input, model);
}
else if (input.matches("((sum)|(avg)) " + ref + " - " + ref)) {
cell = new SumAvgCell(input, model);
}
else if (input.matches(dub + "|" + frac)) {
cell = new NumberCell(input);
}
else if (input.matches("(\\d{1}|\\d{2})/(\\d{1}|\\d{2})/(\\d{2}|\\d{4})")) {
cell = new DateCell(input);
}
else {
cell = new StringCell(input);
}
//sets the cell value
model.setValueAt(cell, row, column);
}
//sets all cell values to null
public void clearTable() {
for (int i = 0; i < HEIGHT; i++) {
for(int j = 0; j < WIDTH; j++) {
model.setValueAt(null, i, j);
}
}
}
}
:
は参考のため、ここでは私のプログラムの主要部分です。
私はそれを実行したときに、getTableCellEditorComponent(...)メソッドは、無限にStackOverflowErrorその結果、自分自身と呼ばれます。これは役に立つかもしれませんが、私はJava Tips Weblogで見つけたTableCellListenerというカスタムセルリスナーを使用しています。 – traviata
私は 'super.'を追加するのを忘れました。今度はその部分を更新しました。 – rdonuk
素晴らしい;それはそれを固定!唯一の他の問題は、superへの呼び出しがJTextFieldにキャストされる必要があることでした。 – traviata