我創建什麼基本上我是副本的Excel。用戶將數據輸入到JTable中,然後對數據進行分析,處理,然後顯示適當類型的Cell的toString()方法,這是我爲其創建了幾個子類的接口。顯示備用toString()與自定義單元格編輯器的方法
當用戶開始編輯FormulaCell時,我希望單元格顯示由getFormula()方法檢索的公式,而不是由toString()方法檢索的評估公式。
我探討了自定義單元格編輯器,但我找不出要覆蓋哪種方法。我覺得代碼將是這樣一個自定義單元格編輯器或任何我需要內部創建:
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。這可能也可能沒有幫助,但我使用了一個名爲TableCellListener的自定義單元偵聽器,我在Java Tips Weblog上找到了這個偵聽器。 – traviata
我只是忘了添加'super.'。現在更新了該部分。 – rdonuk
太棒了;修復它!唯一的另一個複雜情況是,對super的調用需要被轉換爲JTextField。 – traviata