Browse Source

Ensure boolean JTable values are updated as soon as they change in the editor. Fixes #213

pull/214/head
weisj 4 years ago
parent
commit
31b16fbd9e
  1. 9
      core/src/main/java/com/github/weisj/darklaf/ui/table/TableConstants.java
  2. 89
      core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditorDelegate.java
  3. 76
      core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditorToggleButton.java

9
core/src/main/java/com/github/weisj/darklaf/ui/table/TableConstants.java

@ -47,8 +47,13 @@ public interface TableConstants extends CellConstants {
return PropertyUtil.getBooleanProperty(table, DarkTableUI.KEY_RENDER_BOOLEAN_AS_CHECKBOX); return PropertyUtil.getBooleanProperty(table, DarkTableUI.KEY_RENDER_BOOLEAN_AS_CHECKBOX);
} }
static boolean useBooleanEditorForValue(final Object value, final JTable table, final int column) { static boolean useBooleanEditorForValue(final Object value, final JTable table, final int column,
final boolean checkTableProperty) {
return value instanceof Boolean && (Boolean.class.isAssignableFrom(table.getColumnClass(column)) return value instanceof Boolean && (Boolean.class.isAssignableFrom(table.getColumnClass(column))
|| TableConstants.isBooleanRenderingEnabled(table)); || (!checkTableProperty || TableConstants.isBooleanRenderingEnabled(table)));
}
static boolean useBooleanEditorForValue(final Object value, final JTable table, final int column) {
return useBooleanEditorForValue(value, table, column, true);
} }
} }

89
core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditorDelegate.java

@ -31,25 +31,14 @@ import javax.swing.table.TableCellEditor;
import com.github.weisj.darklaf.delegate.TableCellEditorDelegate; import com.github.weisj.darklaf.delegate.TableCellEditorDelegate;
import com.github.weisj.darklaf.ui.cell.CellUtil; import com.github.weisj.darklaf.ui.cell.CellUtil;
import com.github.weisj.darklaf.ui.cell.DarkCellRendererToggleButton;
import com.github.weisj.darklaf.ui.spinner.DarkSpinnerUI; import com.github.weisj.darklaf.ui.spinner.DarkSpinnerUI;
import com.github.weisj.darklaf.ui.table.DarkTableUI; import com.github.weisj.darklaf.ui.table.DarkTableUI;
import com.github.weisj.darklaf.ui.table.TableConstants; import com.github.weisj.darklaf.ui.table.TableConstants;
import com.github.weisj.darklaf.util.PropertyUtil;
public class DarkTableCellEditorDelegate extends TableCellEditorDelegate { public class DarkTableCellEditorDelegate extends TableCellEditorDelegate {
private static final IconWrapper iconWrapper = new IconWrapper(); private static final IconWrapper iconWrapper = new IconWrapper();
private final JToggleButton editorCheckBox = new DarkCellRendererToggleButton.CellCheckBox(true);
private final DarkTableCellEditorToggleButton checkBoxEditor = new DarkTableCellEditorToggleButton(editorCheckBox);
private final JToggleButton editorRadioButton = new DarkCellRendererToggleButton.CellRadioButton(true);
private final DarkTableCellEditorToggleButton radioButtonEditor =
new DarkTableCellEditorToggleButton(editorRadioButton);
private boolean isBooleanEditor;
private TableCellEditor currentEditor;
public DarkTableCellEditorDelegate() { public DarkTableCellEditorDelegate() {
super(new DarkMultiCellEditor()); super(new DarkMultiCellEditor());
} }
@ -58,14 +47,6 @@ public class DarkTableCellEditorDelegate extends TableCellEditorDelegate {
super(editor); super(editor);
} }
@Override
public Object getCellEditorValue() {
if (isBooleanEditor && currentEditor != null) {
return currentEditor.getCellEditorValue();
}
return super.getCellEditorValue();
}
@Override @Override
public boolean isCellEditable(final EventObject anEvent) { public boolean isCellEditable(final EventObject anEvent) {
if (anEvent == null) return super.isCellEditable(null); if (anEvent == null) return super.isCellEditable(null);
@ -74,39 +55,45 @@ public class DarkTableCellEditorDelegate extends TableCellEditorDelegate {
if (DarkTableUI.ignoreKeyCodeOnEdit((KeyEvent) anEvent, table)) return false; if (DarkTableUI.ignoreKeyCodeOnEdit((KeyEvent) anEvent, table)) return false;
} }
if (TableConstants.isBooleanRenderingEnabled(table)) { if (TableConstants.isBooleanRenderingEnabled(table)) {
if (anEvent instanceof MouseEvent && isMouseOverBooleanRenderer((MouseEvent) anEvent, table)) { if (anEvent instanceof MouseEvent) {
return true; Point p = ((MouseEvent) anEvent).getPoint();
int row = table.rowAtPoint(p);
int col = table.columnAtPoint(p);
if (isValidIndex(table, row, col)) {
Object value = table.getValueAt(row, col);
if (TableConstants.useBooleanEditorForValue(value, table, col, false)) {
return insideBooleanRenderer(table, row, col, p);
}
}
} }
} }
return super.isCellEditable(anEvent); return super.isCellEditable(anEvent);
} }
private boolean isMouseOverBooleanRenderer(final MouseEvent anEvent, final JTable table) { private boolean isValidIndex(final JTable table, final int row, final int col) {
Point p = anEvent.getPoint(); return row >= 0 && row < table.getRowCount() && col >= 0 && col < table.getColumnCount();
int row = table.rowAtPoint(p); }
int col = table.columnAtPoint(p);
if (row >= 0 && row < table.getRowCount() && col >= 0 && col < table.getColumnCount()) { private boolean insideBooleanRenderer(final JTable table, final int row, final int col, final Point p) {
Object value = table.getValueAt(row, col); Rectangle rect = table.getCellRect(row, col, false);
if (TableConstants.useBooleanEditorForValue(value, table, col)) { p.x -= rect.x;
Rectangle rect = table.getCellRect(row, col, false); p.y -= rect.y;
p.x -= rect.x; Component editor =
p.y -= rect.y; table.getCellRenderer(row, col).getTableCellRendererComponent(table, true, false, false, row, col);
JToggleButton editor = editor.setBounds(rect);
getBooleanEditor(table).getTableCellEditorComponent(table, true, false, row, col); return editor.contains(p);
editor.setBounds(rect);
return editor.contains(p);
}
}
return false;
} }
@Override @Override
public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected, public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected,
final int row, final int column) { final int row, final int column) {
isBooleanEditor = TableConstants.useBooleanEditorForValue(value, table, column); if (TableConstants.useBooleanEditorForValue(value, table, column)) {
currentEditor = isBooleanEditor ? getBooleanEditor(table) : getDelegate(); table.setValueAt(!(boolean) value, row, column);
table.repaint();
Component editor = currentEditor.getTableCellEditorComponent(table, value, isSelected, row, column); // returning null will stop cell editing immediately.
return null;
}
Component editor = getDelegate().getTableCellEditorComponent(table, value, isSelected, row, column);
editor = prepareEditorComponent(editor, table, value, isSelected, row, column); editor = prepareEditorComponent(editor, table, value, isSelected, row, column);
return editor; return editor;
} }
@ -161,22 +148,4 @@ public class DarkTableCellEditorDelegate extends TableCellEditorDelegate {
} }
return comp; return comp;
} }
protected DarkTableCellEditorToggleButton getBooleanEditor(final JTable table) {
if (PropertyUtil.isPropertyEqual(table, DarkTableUI.KEY_BOOLEAN_RENDER_TYPE,
DarkTableUI.RENDER_TYPE_RADIOBUTTON)) {
return radioButtonEditor;
}
return checkBoxEditor;
}
@Override
public boolean stopCellEditing() {
return super.stopCellEditing();
}
@Override
public void cancelCellEditing() {
super.cancelCellEditing();
}
} }

76
core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditorToggleButton.java

@ -1,76 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.github.weisj.darklaf.ui.table.renderer;
import java.util.EventObject;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.table.TableCellEditor;
import com.github.weisj.darklaf.ui.cell.CellToggleButton;
/** @author Jannis Weis */
public class DarkTableCellEditorToggleButton extends AbstractCellEditor implements TableCellEditor, SwingConstants {
private final JToggleButton toggleButton;
private final Border editorBorder;
public DarkTableCellEditorToggleButton(final JToggleButton toggleButton) {
this.toggleButton = toggleButton;
this.editorBorder = UIManager.getBorder("Table.booleanEditorBorder");
toggleButton.setFocusable(false);
toggleButton.setOpaque(true);
}
@Override
public JToggleButton getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected,
final int row, final int column) {
if (value instanceof Boolean) {
toggleButton.setSelected((Boolean) value);
}
if (toggleButton instanceof CellToggleButton) {
((CellToggleButton) toggleButton).setHasFocus(true);
}
toggleButton.setBorder(editorBorder);
return toggleButton;
}
public JToggleButton getToggleButton() {
return toggleButton;
}
@Override
public Object getCellEditorValue() {
return toggleButton.isSelected();
}
@Override
public boolean isCellEditable(final EventObject anEvent) {
return true;
}
@Override
public boolean shouldSelectCell(final EventObject anEvent) {
return true;
}
}
Loading…
Cancel
Save