2016-03-27 18 views
1

私は基本的に何かをコピーしています。ユーザーが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); 
      } 
     } 
    } 
} 

は参考のため、ここでは私のプログラムの主要部分です。

答えて

4

セルエディタで使用されるテキストを返すgetDetailedText()のようなメソッドをCellインターフェイスに定義します。次に、このメソッドの式をFormulaCellに返します。他のセルについては、toString()を返すことができます。

セル・インタフェース:

public interface Cell { 

    public String getDetailedText(); 
} 

FormulaCell:

public class FormulaCell implements Cell { 

    public String getDetailedText() { 
     return formula; 
    } 
} 

他のセル(あなたが各セルの別のテキストを表示したい場合はちょうどここに戻っ):

public class OtherCell implements Cell { 

    public String getDetailedText() { 
     return toString(); 
    } 
} 

次に作成セルエディタを開き、テーブルのデフォルトエディタとして設定します。

デフォルトのセルエディタ:テーブルへ

public class MyDefaultCellEditor extends DefaultCellEditor { 
    public MyDefaultCellEditor() { 
     super(new JTextField()); 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, 
      int column) { 
     JTextField textField = (JTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column); 
     Cell cell = (Cell) value; 

     textField.setText(cell.getEditorText()); 
     return textField; 
    } 
} 

セット:

table.setDefaultEditor(Object.class, new MyDefaultCellEditor()); 
+0

私はそれを実行したときに、getTableCellEditorComponent(...)メソッドは、無限にStackOverflowErrorその結果、自分自身と呼ばれます。これは役に立つかもしれませんが、私はJava Tips Weblogで見つけたTableCellListenerというカスタムセルリスナーを使用しています。 – traviata

+0

私は 'super.'を追加するのを忘れました。今度はその部分を更新しました。 – rdonuk

+1

素晴らしい;それはそれを固定!唯一の他の問題は、superへの呼び出しがJTextFieldにキャストされる必要があることでした。 – traviata

関連する問題