- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个包含 N 行和 2 列的 JTable,我需要实现一个自定义 CellEditor 类来访问每个单元格的数据输入
table.getCellEditor(int row, int column).getCellEditorValue()
我使用过这个CellEditor类
class MyEditor extends DefaultCellEditor {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextField textField;
private boolean valueSet;
public MyEditor() {
super(new JTextField());
}
@Override
public boolean isCellEditable(EventObject eo) {
System.err.println("isCellEditable");
if (eo instanceof KeyEvent) {
KeyEvent ke = (KeyEvent) eo;
System.err.println("key event: " + ke.getKeyChar());
textField.setText(String.valueOf(ke.getKeyChar()));
valueSet = true;
} else {
valueSet = false;
}
return true;
}
}
但不足以访问正确单元格位置中的数据...(并且似乎所有表格都被视为整个单元格)
我发现的所有示例都与使用单元格编辑器阻止编辑单元格(如果输入不正确)有关,但任何清晰的内容都足以帮助我解决问题。
PS如果您想详细了解整个界面(不)如何工作,则整个代码如下:
public class CompileDataJob extends JFrame {
private boolean DEBUG = false;
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CompileDataJob frame = new CompileDataJob();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public CompileDataJob() {
setTitle("Inserisci i parametri dei lavori");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 551, 293);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
JPanel panel_1 = new JPanel();
final JTable table = new JTable(new MyTableModel());
JButton btnNewButton = new JButton(" OK ");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
DataJobManager.azzeraListaLavori();
int numJob=DataJobManager.loadNumeroLavori();
LinkedList<Job> listaLavori=new LinkedList<Job>();
String id;
int time;
for (int rowIndex=0; rowIndex<numJob; rowIndex++){
id=(String)(table.getCellEditor(rowIndex,0).getCellEditorValue());
time=Integer.parseInt(((String)((table.getCellEditor(rowIndex, 1)).getCellEditorValue())));
Job l=new Job(id,time);
listaLavori.add(l);
}
DataJobManager.saveListaLavori(listaLavori);
CompileDataJob.this.dispose();
JOptionPane.showMessageDialog(CompileDataJob.this,"Data Saved");
}catch(Exception ecc){
JOptionPane.showMessageDialog(CompileDataJob.this,"Error during the saving.");
}
}
});
panel_1.add(btnNewButton);
JButton btnNewButton_1 = new JButton("Cancel");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
CompileDataJob.this.dispose();
}
});
JPanel panel = new JPanel();
table.setDefaultEditor(Object.class,new MyEditor());
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
table.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
int viewRow = table.getSelectedRow();
JLabel statusText=new JLabel();
if (viewRow < 0) {
//Selection got filtered away.
statusText.setText("");
} else {
int modelRow =
table.convertRowIndexToModel(viewRow);
statusText.setText(
String.format("Selected Row in view: %d. " +
"Selected Row in model: %d.",
viewRow, modelRow));
}
}
}
);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Set up column sizes.
initColumnSizes(table);
panel_1.add(btnNewButton_1);
GroupLayout gl_contentPane = new GroupLayout(contentPane);
gl_contentPane.setHorizontalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING, false)
.addComponent(panel_1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(panel, GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE))
.addContainerGap())
);
gl_contentPane.setVerticalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 213, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 61, Short.MAX_VALUE)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(11)
.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addContainerGap(12, Short.MAX_VALUE))
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(5)
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
.addContainerGap())
);
panel.setLayout(gl_panel);
contentPane.setLayout(gl_contentPane);
}
private void initColumnSizes(JTable table) {
MyTableModel model = (MyTableModel)table.getModel();
TableColumn column = null;
Component comp = null;
int headerWidth = 0;
int cellWidth = 0;
Object[] longValues = model.longValues;
TableCellRenderer headerRenderer =
table.getTableHeader().getDefaultRenderer();
for (int i = 0; i < 2; i++) {
column = table.getColumnModel().getColumn(i);
comp = headerRenderer.getTableCellRendererComponent(
null, column.getHeaderValue(),
false, false, 0, 0);
headerWidth = comp.getPreferredSize().width;
comp = table.getDefaultRenderer(model.getColumnClass(i)).
getTableCellRendererComponent(
table, longValues[i],
false, false, 0, i);
cellWidth = comp.getPreferredSize().width;
if (DEBUG) {
System.out.println("Initializing width of column "
+ i + ". "
+ "headerWidth = " + headerWidth
+ "; cellWidth = " + cellWidth);
}
column.setPreferredWidth(Math.max(headerWidth, cellWidth));
}
}
class MyEditor extends DefaultCellEditor {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextField textField;
private boolean valueSet;
public MyEditor() {
super(new JTextField());
}
@Override
public boolean isCellEditable(EventObject eo) {
System.err.println("isCellEditable");
if (eo instanceof KeyEvent) {
KeyEvent ke = (KeyEvent) eo;
System.err.println("key event: " + ke.getKeyChar());
textField.setText(String.valueOf(ke.getKeyChar()));
//textField.select(1,1);
//textField.setCaretPosition(1);
//textField.moveCaretPosition(1);
valueSet = true;
} else {
valueSet = false;
}
return true;
}
}
class MyTableModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = 1L;
private String[] columnNames = {"Nome Job", "Durata"};
int numJob=DataJobManager.loadNumeroLavori();
private Object[][] data = getDatiDefaultTabella();
public class Job {
public int time; // Should n't this be a long?
public String jobName;
}
public Object[][] getDatiDefaultTabella(){
Object[][] tabella=new Object[numJob][2];
for(int i=0; i<numJob; i++){
for(int j=0; j<2; j++){
tabella[i][j]="inserisci dati";
}
}
return tabella;
}
public Object[][] getTabella(){
return data;
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return numJob;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public Class getRowClass(int r) {
return getValueAt(r, 0).getClass();
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
return true;
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public void setValueAt(Object value, int row, int col) {
if (DEBUG) {
System.out.println("Setting value at " + row + "," + col
+ " to " + value
+ " (an instance of "
+ value.getClass() + ")");
}
data[row][col] = value;
fireTableCellUpdated(row, col);
if (DEBUG) {
System.out.println("New value of data:");
printDebugData();
}
}
private void printDebugData() {
int numRows = getRowCount();
int numCols = getColumnCount();
for (int i=0; i < numRows; i++) {
System.out.print(" row " + i + ":");
for (int j=0; j < numCols; j++) {
System.out.print(" " + data[i][j]);
}
System.out.println();
}
System.out.println("--------------------------");
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
public void run() {
try {
CompileDataJob frame = new CompileDataJob();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
最佳答案
好吧,我想我明白了。我稍微优化了你的代码并删除了我不需要的东西。您可以重新添加。
这是编译数据作业
public class CompileDataJob extends JFrame {
final boolean DEBUG = false;
private final JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CompileDataJob frame = new CompileDataJob();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public CompileDataJob() {
setTitle("Inserisci i parametri dei lavori");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 551, 293);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
JPanel panel_1 = new JPanel();
final JTable table = new JTable(new MyTableModel());
JButton add = new JButton(" ADD ");
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
((MyTableModel)table.getModel()).addRow(new Job(0, ""));
}
});
JButton btnNewButton = new JButton(" OK ");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
DataJobManager.saveListaLavori(((MyTableModel)table.getModel()).getJobs());
CompileDataJob.this.dispose();
JOptionPane.showMessageDialog(CompileDataJob.this,"Data Saved");
}catch(Exception ecc){
JOptionPane.showMessageDialog(CompileDataJob.this,"Error during the saving.");
}
}
});
panel_1.add(btnNewButton);
panel_1.add(add);
JButton btnNewButton_1 = new JButton("Cancel");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
CompileDataJob.this.dispose();
}
});
JPanel panel = new JPanel();
// table.setDefaultEditor(Object.class,new MyEditor());
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
panel_1.add(btnNewButton_1);
GroupLayout gl_contentPane = new GroupLayout(contentPane);
gl_contentPane.setHorizontalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING, false)
.addComponent(panel_1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(panel, GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE))
.addContainerGap())
);
gl_contentPane.setVerticalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 213, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 61, Short.MAX_VALUE)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(11)
.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addContainerGap(12, Short.MAX_VALUE))
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(5)
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
.addContainerGap())
);
panel.setLayout(gl_panel);
contentPane.setLayout(gl_contentPane);
}
}
这是工作
public class Job {
public int time = 500; // Should n't this be a long?
public String jobName;
public boolean processed = false;
public Job(int time, String jobName) {
this.time = time;
this.jobName = jobName;
}
public boolean isProcessed() {
return processed;
}
}
这是您的 TableModel,它是可优化的,但可以工作......
class MyTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private final List<Job> objects = new ArrayList<Job>();
private final String[] columnNames = { "Nome Job", "Durata", "processed" };
private final Class<?>[] metaModell = new Class[]{String.class, Integer.class, Boolean.class};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return objects.size();
}
@Override
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
if (row >= objects.size())
return null;
Job job = getRow(row);
switch (col) {
case 0:
return job.jobName;
case 1:
return job.time;
case 2:
return job.isProcessed();
}
return null;
}
private Job getRow(int row) {
return objects.get(row);
}
@Override
public Class<?> getColumnClass(int c) {
if (c < metaModell.length)
return metaModell[c];
return Object.class;
}
@Override
public boolean isCellEditable(int row, int col) {
return col >= 0 && col < columnNames.length;
}
@Override
public void setValueAt(Object value, int row, int col) {
Job job = getRow(row);
switch (col) {
case 0:
job.jobName = (String) value;
break;
case 1:
job.time = (Integer) value;
break;
// case 2:
// job.processed = (Boolean) value;
// break;
}
fireTableDataChanged();
}
public List<Job> getJobs() {
return objects;
}
public void addRow(Job job) {
this.objects.add(job);
fireTableDataChanged();
}
}
正如您将看到的,我删除了所有 MyEditor 内容以及编辑器内容中复杂的 getValues 内容。相反,我向表模型添加了方法 addJob()
和 getJobs
。
关于java - 为具有 2 列(字符串、整数)和 n 行的 JTable 实现自定义 CellEditor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10077632/
我正在 csv 上使用 hadoop 来分析一些数据。我使用sql/mysql(不确定)来分析数据,现在陷入了僵局。 我花了好几个小时在谷歌上搜索,却没有找到任何相关的东西。我需要一个查询,在该查询中
我正在为 Bootstrap 网格布局的“简单”任务而苦苦挣扎。我希望在大视口(viewport)上有 4 列,然后在中型设备上有 2 列,最后在较小的设备上只有 1 列。 当我测试我的代码片段时,似
对于这个令人困惑的标题,我深表歉意,我想不出这个问题的正确措辞。相反,我只会给你背景信息和目标: 这是在一个表中,一个人可能有也可能没有多行数据,这些行可能包含相同的 activity_id 值,也可
具有 3 列的数据库表 - A int , B int , C int 我的问题是: 如何使用 Sequelize 结果找到 A > B + C const countTasks = await Ta
我在通过以下功能编写此查询时遇到问题: 首先按第 2 列 DESC 排序,然后从“不同的第 1 列”中选择 只有 Column1 是 DISTINCT 此查询没有帮助,因为它首先从第 1 列中进行选择
使用 Bootstrap 非常有趣和有帮助,目前我在创建以下需求时遇到问题。 “使用 bootstrap 在桌面上有 4 列,在平板电脑上有 2 列,在移动设备上有 1 列”谁能告诉我正确的结构 最佳
我是 R 新手,正在问一个非常基本的问题。当然,我在尝试从所提供的示例中获取指导的同时做了功课here和 here ,但无法在我的案例中实现这个想法,即可能是由于我的问题中的比较维度更大。 我的实
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个 df , delta1 delta2 0 -1 2 0 -1 0 0 0 我想知道如何分配 delt
您好,我想知道是否可以执行以下操作。显然,我已经尝试在 phpMyAdmin 中运行它,但出现错误。也许还有另一种方式来编写此查询。 SELECT * FROM eat_eat_restaurants
我有 2 个列表(标题和数据值)。我想要将数据值列 1 匹配并替换为头文件列 1,以获得与 dataValue 列 1 和标题值列 2 匹配的值 头文件 TotalLoad,M0001001 Hois
我有两个不同长度的文件,file2 是一个很大的引用文件,我从中提取文件 1 的数据。 我有一行 awk,我通常会对其进行调整以在我的文件中进行查找和替换,但它总是在同一列中进行查找和替换。 所以对于
假设我有两个表,如下所示。 create table contract( c_ID number(1) primary key, c_name varchar2(50) not
我有一个带有 varchar 列的 H2 表,其检查约束定义如下: CONSTRAINT my_constraint CHECK (varchar_field <> '') 以下插入语句失败,但当我删
这是最少量的代码,可以清楚地说明我的问题: One Two Three 前 2 个 div 应该是 2 个左列。第三个应该占据页面的其余部分。最后,我将添加选项来隐藏和
在 Azure 中的 Log Analytics 中,我为 VM Heartbeat 选择一个预定义查询,我在编辑器中运行查询正常,但当我去创建警报时,我不断收到警报“查询未返回 TimeGenera
在 Azure 中的 Log Analytics 中,我为 VM Heartbeat 选择一个预定义查询,我在编辑器中运行查询正常,但当我去创建警报时,我不断收到警报“查询未返回 TimeGenera
今天我开始使用 JexcelApi 并遇到了这个:当您尝试从特定位置获取元素时,不是像您通常期望的那样使用sheet.getCell(row,col),而是使用sheet.getCell(col,ro
我有一个包含 28 列的数据库。第一列是代码,第二列是名称,其余是值。 public void displayData() { con.Open(); MySqlDataAdapter
我很沮丧:每当我缩小这个网页时,一切都变得一团糟。我如何将网页居中,以便我可以缩小并且元素不会被错误定位。 (它应该是 2 列,但所有内容都合并为 1)我试过 但由于某种原因,这不起作用。 www.o
我是一名优秀的程序员,十分优秀!