Предположим, что я создаю пользовательский JTable с CustomDataModel и CustomTableListener. Предположим, что они работают славно.Пользовательский DataModel для возврата JTable Тип безопасного значения
Теперь предположим, что в реализации, что каждый JTable, как гарантируется, имеет свой первый ряд, заполненный безопасными по типу данных, и что эти данные никогда не будут удалены, изменены только и не будут установлены в null. (используя JComboBoxes в качестве своего редактора и пустые строки и 0, которые отображаются как пустые строки, являются единственным «пустым» выбором)
Сейчас; Я хочу написать метод, который использует getColumnClass для возврата типизированных данных.
Из того, что я прочитал, я должен буду использовать следующие методы в сочетании:
class CustomDataModel extends AbstractTableModel {
...
//implement data struc and other methods (full testable code further down below in the SSCCE)
...
/**
* Guaranteed to return a class based on this table's construction
* @param c
* @return
*/
@Override
public Class getColumnClass(int c){
return getValueAt(0,c).getClass();
}
...
public <T> T returnType(int row, int column) {
//the following will not compile - and I'm stuck, don't know how to
//use getColumnClass to return type-specific data
return getColumnClass(column).cast(getValueAt(row,column));
}
}
NetBeans рассказывает мне, что возвращается литая Призыва Object, но я был уверен, что литой (Object объект) возвращается T, где T - тип этого в литье.
Чем больше я думаю об этом, тем больше я верю, что я, что хочу, невозможно. На самом деле это не обязательно, но это позволит избежать бросков - хотя я предполагаю, что это заставит делать броски, если моя текущая реализация получит «фиксированную» и набрав-отпечаток, выполненную с помощью ручной кастинга.
В настоящее время; в SSCCE я использую system.out.println, чтобы просто печатать - который принимает ссылку на объект и вызывает его метод toString(), но методы или действия, которые я хочу выполнить, не обязательно должны привязываться к параметру Object ,
Цель состоит в том, чтобы непосредственно получить тип хранимых данных; что на самом деле невозможно, если он хранится в качестве ссылки на объект, не возвращая его в исходный тип. Предположим ... Если не используются дженерики? Я не знаю - любая помощь ценится!
SSCCE
//package utility;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
/**
* @author Sean
*/
public class UnitTesting extends JPanel{
public UnitTesting() {
super(new GridLayout(1,0));
JTable table = createAJTable();
table.getTableHeader().setReorderingAllowed(false);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Normally here JComboBoxes are set as the Editors - SSCCE will use dummy test data
//Add the scroll pane to this panel.
add(scrollPane);
//Test the data Types - I want to retrieve type-specific data to avoid casting
CustomModel dataModel = (CustomModel)table.getModel();
Object val;
for(int row = 0; row < dataModel.getRowCount(); row++){
//Row possibility
doSomeThings(row, dataModel);
for(int col = 0; col < dataModel.getColumnCount(); col++){
//Here's the old way of going about this. (also could invoke getColumnClass())
val = dataModel.getValueAt(row, col);
System.out.println(val + " : " + val.getClass());
//Overloaded possibility - needs typed data
// doSomeAction(dataModel.typedValueAt(row, col));
}
}
}
private JTable createAJTable() {
return new JTable(new CustomModel(new String[]{"Col1", "Col2", "Col3", "Col4", "Col5"}));
}
private void doSomeAction(String str){
//Do things with strings
}
private void doSomeAction(int number){
//Do things with integers
}
private void doSomeThings(int row, CustomModel dataModel) {
String col1Data, col2Data, col5Data;
int col3Num, col4Num;
//Retrieve data and store it in typed local variable (need casting or typed retrieval)
//Do things with the Strings and Integers together
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
UnitTesting newContentPane = new UnitTesting();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
/*
* Set Look and feel here; taken out for SSCCE
*/
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
class CustomModel extends AbstractTableModel {
//Dummy data for the SSCCE
private List<String> columnHeadings;
private List<List<Object>> data;
CustomModel(String[] cols){
data = new ArrayList<>();
columnHeadings = Arrays.asList(cols);
ArrayList<Object> testRow = new ArrayList<>();
testRow.add("String");
testRow.add("Str");
testRow.add(0);
testRow.add(5);
testRow.add("Strong");
data.add(testRow);
}
//This is the method I want to create
// public <T> T typedValueAt(int row, int column) {
// return getColumnClass(column).cast(getValueAt(row,column));
// }
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return columnHeadings.size();
}
@Override
public String getColumnName(int columnIndex) {
return columnHeadings.get(columnIndex);
}
@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0,c).getClass();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
//For the SSCCE we'll just test with one row of uneditable data
return false;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data.get(rowIndex).get(columnIndex);
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//Normally check for row existence and populate necessary rows - but for SSCCE just this will suffice
data.get(rowIndex).set(columnIndex, aValue);
}
}
}
Глядя на следующие ссылки - спуск по общей трассе данных. http://stackoverflow.com/questions/13229979/java-nested-generic-type-mismatch http://stackoverflow.com/questions/8058470/nested-type-parameters-in-java?rq=1 –