Table: support rounded selection (issue #844)

This commit is contained in:
Karl Tauber
2024-06-24 18:36:44 +02:00
parent 72a4c00e72
commit 9ffda72ae3
11 changed files with 644 additions and 55 deletions

View File

@@ -324,8 +324,7 @@ public class FlatListUI
(rendererComponent instanceof DefaultListCellRenderer || (rendererComponent instanceof DefaultListCellRenderer ||
rendererComponent instanceof BasicComboBoxRenderer) && rendererComponent instanceof BasicComboBoxRenderer) &&
(selectionArc > 0 || (selectionArc > 0 ||
(selectionInsets != null && (selectionInsets != null && !FlatUIUtils.isInsetsEmpty( selectionInsets ))) )
(selectionInsets.top != 0 || selectionInsets.left != 0 || selectionInsets.bottom != 0 || selectionInsets.right != 0))) )
{ {
// Because selection painting is done in the cell renderer, it would be // Because selection painting is done in the cell renderer, it would be
// necessary to require a FlatLaf specific renderer to implement rounded selection. // necessary to require a FlatLaf specific renderer to implement rounded selection.
@@ -374,7 +373,15 @@ public class FlatListUI
rendererPane.paintComponent( g, rendererComponent, list, cx, rowBounds.y, cw, rowBounds.height, true ); rendererPane.paintComponent( g, rendererComponent, list, cx, rowBounds.y, cw, rowBounds.height, true );
} }
/** @since 3 */ /**
* Paints (rounded) cell selection.
* Supports {@link #selectionArc} and {@link #selectionInsets}.
* <p>
* <b>Note:</b> This method is only invoked if either selection arc
* is greater than zero or if selection insets are not empty.
*
* @since 3
*/
protected void paintCellSelection( Graphics g, int row, int x, int y, int width, int height ) { protected void paintCellSelection( Graphics g, int row, int x, int y, int width, int height ) {
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight; float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f ); arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
@@ -440,7 +447,8 @@ public class FlatListUI
* Paints a cell selection at the given coordinates. * Paints a cell selection at the given coordinates.
* The selection color must be set on the graphics context. * The selection color must be set on the graphics context.
* <p> * <p>
* This method is intended for use in custom cell renderers. * This method is intended for use in custom cell renderers
* to support {@link #selectionArc} and {@link #selectionInsets}.
* *
* @since 3 * @since 3
*/ */

View File

@@ -65,8 +65,28 @@ public class FlatTableCellBorder
return super.getLineColor(); return super.getLineColor();
} }
@Override
public int getArc() {
if( c != null ) {
Integer selectionArc = getStyleFromTableUI( c, ui -> ui.selectionArc );
if( selectionArc != null )
return selectionArc;
}
return super.getArc();
}
@Override @Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
if( c != null ) {
Insets selectionInsets = getStyleFromTableUI( c, ui -> ui.selectionInsets );
if( selectionInsets != null ) {
x += selectionInsets.left;
y += selectionInsets.top;
width -= selectionInsets.left + selectionInsets.right;
height -= selectionInsets.top + selectionInsets.bottom;
}
}
this.c = c; this.c = c;
super.paintBorder( c, g, x, y, width, height ); super.paintBorder( c, g, x, y, width, height );
this.c = null; this.c = null;

View File

@@ -24,6 +24,8 @@ import java.awt.EventQueue;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
@@ -95,6 +97,8 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Table.intercellSpacing Dimension * @uiDefault Table.intercellSpacing Dimension
* @uiDefault Table.selectionInactiveBackground Color * @uiDefault Table.selectionInactiveBackground Color
* @uiDefault Table.selectionInactiveForeground Color * @uiDefault Table.selectionInactiveForeground Color
* @uiDefault Table.selectionInsets Insets
* @uiDefault Table.selectionArc int
* @uiDefault Table.paintOutsideAlternateRows boolean * @uiDefault Table.paintOutsideAlternateRows boolean
* @uiDefault Table.editorSelectAllOnStartEditing boolean * @uiDefault Table.editorSelectAllOnStartEditing boolean
* *
@@ -123,6 +127,8 @@ public class FlatTableUI
@Styleable protected Color selectionForeground; @Styleable protected Color selectionForeground;
@Styleable protected Color selectionInactiveBackground; @Styleable protected Color selectionInactiveBackground;
@Styleable protected Color selectionInactiveForeground; @Styleable protected Color selectionInactiveForeground;
/** @since 3.5 */ @Styleable protected Insets selectionInsets;
/** @since 3.5 */ @Styleable protected int selectionArc;
// for FlatTableCellBorder // for FlatTableCellBorder
/** @since 2 */ @Styleable protected Insets cellMargins; /** @since 2 */ @Styleable protected Insets cellMargins;
@@ -162,6 +168,8 @@ public class FlatTableUI
selectionForeground = UIManager.getColor( "Table.selectionForeground" ); selectionForeground = UIManager.getColor( "Table.selectionForeground" );
selectionInactiveBackground = UIManager.getColor( "Table.selectionInactiveBackground" ); selectionInactiveBackground = UIManager.getColor( "Table.selectionInactiveBackground" );
selectionInactiveForeground = UIManager.getColor( "Table.selectionInactiveForeground" ); selectionInactiveForeground = UIManager.getColor( "Table.selectionInactiveForeground" );
selectionInsets = UIManager.getInsets( "Table.selectionInsets" );
selectionArc = UIManager.getInt( "Table.selectionArc" );
toggleSelectionColors(); toggleSelectionColors();
@@ -477,6 +485,10 @@ public class FlatTableUI
}; };
} }
// rounded selection or selection insets
if( selectionArc > 0 || (selectionInsets != null && !FlatUIUtils.isInsetsEmpty( selectionInsets )) )
g = new RoundedSelectionGraphics( g, UIManager.getColor( "Table.alternateRowColor" ) );
super.paint( g, c ); super.paint( g, c );
} }
@@ -535,7 +547,7 @@ public class FlatTableUI
int x = viewport.getComponentOrientation().isLeftToRight() ? 0 : viewportWidth - tableWidth; int x = viewport.getComponentOrientation().isLeftToRight() ? 0 : viewportWidth - tableWidth;
for( int y = tableHeight, row = rowCount; y < viewportHeight; y += rowHeight, row++ ) { for( int y = tableHeight, row = rowCount; y < viewportHeight; y += rowHeight, row++ ) {
if( row % 2 != 0 ) if( row % 2 != 0 )
g.fillRect( x, y, tableWidth, rowHeight ); paintAlternateRowBackground( g, -1, -1, x, y, tableWidth, rowHeight );
} }
// add listener on demand // add listener on demand
@@ -547,6 +559,239 @@ public class FlatTableUI
} }
} }
/**
* Paints (rounded) alternate row background.
* Supports {@link #selectionArc} and {@link #selectionInsets}.
* <p>
* <b>Note:</b> This method is only invoked if either selection arc
* is greater than zero or if selection insets are not empty.
*
* @since 3.5
*/
protected void paintAlternateRowBackground( Graphics g, int row, int column, int x, int y, int width, int height ) {
Insets insets = (selectionInsets != null) ? (Insets) selectionInsets.clone() : null;
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
if( column >= 0 ) {
// selection insets
// selection arc
if( column > 0 ) {
if( insets != null )
insets.left = 0;
if( table.getComponentOrientation().isLeftToRight() )
arcTopLeft = arcBottomLeft = 0;
else
arcTopRight = arcBottomRight = 0;
}
if( column < table.getColumnCount() - 1 ) {
if( insets != null )
insets.right = 0;
if( table.getComponentOrientation().isLeftToRight() )
arcTopRight = arcBottomRight = 0;
else
arcTopLeft = arcBottomLeft = 0;
}
}
FlatUIUtils.paintSelection( (Graphics2D) g, x, y, width, height,
UIScale.scale( insets ), arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight, 0 );
}
//TODO test if scaled (on Windows)
/**
* Paints (rounded) cell selection.
* Supports {@link #selectionArc} and {@link #selectionInsets}.
* <p>
* <b>Note:</b> This method is only invoked if either selection arc
* is greater than zero or if selection insets are not empty.
*
* @since 3.5
*/
protected void paintCellSelection( Graphics g, int row, int column, int x, int y, int width, int height ) {
boolean rowSelAllowed = table.getRowSelectionAllowed();
boolean colSelAllowed = table.getColumnSelectionAllowed();
boolean rowSelOnly = rowSelAllowed && !colSelAllowed;
boolean colSelOnly = colSelAllowed && !rowSelAllowed;
boolean cellOnlySel = rowSelAllowed && colSelAllowed;
// get selection state of surrounding cells
boolean leftSelected = (column > 0 && (rowSelOnly || table.isCellSelected( row, column - 1 )));
boolean topSelected = (row > 0 && (colSelOnly || table.isCellSelected( row - 1, column )));
boolean rightSelected = (column < table.getColumnCount() - 1 && (rowSelOnly || table.isCellSelected( row, column + 1 )));
boolean bottomSelected = (row < table.getRowCount() - 1 && (colSelOnly || table.isCellSelected( row + 1, column )));
if( !table.getComponentOrientation().isLeftToRight() ) {
boolean temp = leftSelected;
leftSelected = rightSelected;
rightSelected = temp;
}
// selection insets
// (insets are applied to whole row if row-only selection is used,
// or to whole column if column-only selection is used,
// or to cell if cell selection is used)
Insets insets = (selectionInsets != null) ? (Insets) selectionInsets.clone() : null;
if( insets != null ) {
if( rowSelOnly && leftSelected )
insets.left = 0;
if( rowSelOnly && rightSelected )
insets.right = 0;
if( colSelOnly && topSelected )
insets.top = 0;
if( colSelOnly && bottomSelected )
insets.bottom = 0;
}
// selection arc
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
if( selectionArc > 0 ) {
// note that intercellSpacing is not considered as a gap because
// grid lines are usually painted to intercell space
boolean hasRowGap = (rowSelOnly || cellOnlySel) && insets != null && (insets.top != 0 || insets.bottom != 0);
boolean hasColGap = (colSelOnly || cellOnlySel) && insets != null && (insets.left != 0 || insets.right != 0);
if( leftSelected && !hasColGap )
arcTopLeft = arcBottomLeft = 0;
if( rightSelected && !hasColGap )
arcTopRight = arcBottomRight = 0;
if( topSelected && !hasRowGap )
arcTopLeft = arcTopRight = 0;
if( bottomSelected && !hasRowGap )
arcBottomLeft = arcBottomRight = 0;
}
FlatUIUtils.paintSelection( (Graphics2D) g, x, y, width, height,
UIScale.scale( insets ), arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight, 0 );
}
/**
* Paints a cell selection at the given coordinates.
* The selection color must be set on the graphics context.
* <p>
* This method is intended for use in custom cell renderers to support
* {@link #selectionArc} and {@link #selectionInsets}.
*
* @since 3.5
*/
public static void paintCellSelection( JTable table, Graphics g, int row, int column, int x, int y, int width, int height ) {
if( !(table.getUI() instanceof FlatTableUI) )
return;
FlatTableUI ui = (FlatTableUI) table.getUI();
ui.paintCellSelection( g, row, column, x, y, width, height );
}
//---- class RoundedSelectionGraphics -------------------------------------
/**
* Because selection painting is done in the cell renderer, it would be
* necessary to require a FlatLaf specific renderer to implement rounded selection.
* Using a LaF specific renderer was avoided because often a custom renderer is
* already used in applications. Then either the rounded selection is not used,
* or the application has to be changed to extend a FlatLaf renderer.
* <p>
* To solve this, a graphics proxy is used that paints rounded selection
* if row/column/cell is selected and the renderer wants to fill the background.
*/
private class RoundedSelectionGraphics
extends Graphics2DProxy
{
private final Color alternateRowColor;
// used to avoid endless loop in case that paintCellSelection() invokes
// g.fillRect() with full bounds (selectionInsets is 0,0,0,0)
private boolean inPaintSelection;
RoundedSelectionGraphics( Graphics delegate, Color alternateRowColor ) {
super( (Graphics2D) delegate );
this.alternateRowColor = alternateRowColor;
}
@Override
public Graphics create() {
return new RoundedSelectionGraphics( super.create(), alternateRowColor );
}
@Override
public Graphics create( int x, int y, int width, int height ) {
return new RoundedSelectionGraphics( super.create( x, y, width, height ), alternateRowColor );
}
@Override
public void fillRect( int x, int y, int width, int height ) {
if( fillCellSelection( x, y, width, height ) )
return;
super.fillRect( x, y, width, height );
}
@Override
public void fill( Shape shape ) {
if( shape instanceof Rectangle2D ) {
Rectangle2D r = (Rectangle2D) shape;
double x = r.getX();
double y = r.getY();
double width = r.getWidth();
double height = r.getHeight();
if( x == (int) x && y == (int) y && width == (int) width && height == (int) height ) {
if( fillCellSelection( (int) x, (int) y, (int) width, (int) height ) )
return;
}
}
super.fill( shape );
}
private boolean fillCellSelection( int x, int y, int width, int height ) {
if( inPaintSelection )
return false;
Color color;
Component rendererComponent;
if( x == 0 && y == 0 &&
((color = getColor()) == table.getSelectionBackground() ||
(alternateRowColor != null && color == alternateRowColor)) &&
(rendererComponent = findActiveRendererComponent()) != null &&
width == rendererComponent.getWidth() &&
height == rendererComponent.getHeight() )
{
Point location = rendererComponent.getLocation();
int row = table.rowAtPoint( location );
int column = table.columnAtPoint( location );
if( row >= 0 && column >= 0 ) {
inPaintSelection = true;
if( color == table.getSelectionBackground() )
paintCellSelection( this, row, column, x, y, width, height );
else
paintAlternateRowBackground( this, row, column, x, y, width, height );
inPaintSelection = false;
return true;
}
}
return false;
}
/**
* A CellRendererPane may contain multiple components, if multiple renderers
* are used. Inactive renderer components have size {@code 0x0}.
*/
private Component findActiveRendererComponent() {
int count = rendererPane.getComponentCount();
for( int i = 0; i < count; i++ ) {
Component c = rendererPane.getComponent( i );
if( c.getWidth() > 0 && c.getHeight() > 0 )
return c;
}
return null;
}
}
//---- class OutsideAlternateRowsListener --------------------------------- //---- class OutsideAlternateRowsListener ---------------------------------
/** /**

View File

@@ -124,6 +124,11 @@ public class FlatUIUtils
dest.right = src.right; dest.right = src.right;
} }
/** @since 3.5 */
public static boolean isInsetsEmpty( Insets insets ) {
return insets.top == 0 && insets.left == 0 && insets.bottom == 0 && insets.right == 0;
}
public static Color getUIColor( String key, int defaultColorRGB ) { public static Color getUIColor( String key, int defaultColorRGB ) {
Color color = UIManager.getColor( key ); Color color = UIManager.getColor( key );
return (color != null) ? color : new Color( defaultColorRGB ); return (color != null) ? color : new Color( defaultColorRGB );

View File

@@ -800,6 +800,8 @@ public class TestFlatStyleableInfo
"selectionForeground", Color.class, "selectionForeground", Color.class,
"selectionInactiveBackground", Color.class, "selectionInactiveBackground", Color.class,
"selectionInactiveForeground", Color.class, "selectionInactiveForeground", Color.class,
"selectionInsets", Insets.class,
"selectionArc", int.class,
// FlatTableCellBorder // FlatTableCellBorder
"cellMargins", Insets.class, "cellMargins", Insets.class,

View File

@@ -305,6 +305,9 @@ public class TestFlatStyleableValue
testColor( c, ui, "buttonPressedArrowColor", 0x123456 ); testColor( c, ui, "buttonPressedArrowColor", 0x123456 );
testColor( c, ui, "popupBackground", 0x123456 ); testColor( c, ui, "popupBackground", 0x123456 );
testInsets( c, ui, "popupInsets", 1,2,3,4 );
testInsets( c, ui, "selectionInsets", 1,2,3,4 );
testInteger( c, ui, "selectionArc", 123 );
// border // border
flatRoundBorder( c, ui ); flatRoundBorder( c, ui );
@@ -367,6 +370,8 @@ public class TestFlatStyleableValue
testColor( c, ui, "selectionForeground", 0x123456 ); testColor( c, ui, "selectionForeground", 0x123456 );
testColor( c, ui, "selectionInactiveBackground", 0x123456 ); testColor( c, ui, "selectionInactiveBackground", 0x123456 );
testColor( c, ui, "selectionInactiveForeground", 0x123456 ); testColor( c, ui, "selectionInactiveForeground", 0x123456 );
testInsets( c, ui, "selectionInsets", 1,2,3,4 );
testInteger( c, ui, "selectionArc", 123 );
// FlatListCellBorder // FlatListCellBorder
testInsets( c, ui, "cellMargins", 1,2,3,4 ); testInsets( c, ui, "cellMargins", 1,2,3,4 );
@@ -802,6 +807,8 @@ public class TestFlatStyleableValue
testColor( c, ui, "selectionForeground", 0x123456 ); testColor( c, ui, "selectionForeground", 0x123456 );
testColor( c, ui, "selectionInactiveBackground", 0x123456 ); testColor( c, ui, "selectionInactiveBackground", 0x123456 );
testColor( c, ui, "selectionInactiveForeground", 0x901324 ); testColor( c, ui, "selectionInactiveForeground", 0x901324 );
testInsets( c, ui, "selectionInsets", 1,2,3,4 );
testInteger( c, ui, "selectionArc", 123 );
// FlatTableCellBorder // FlatTableCellBorder
testInsets( c, ui, "cellMargins", 1,2,3,4 ); testInsets( c, ui, "cellMargins", 1,2,3,4 );
@@ -931,6 +938,8 @@ public class TestFlatStyleableValue
testColor( c, ui, "selectionInactiveBackground", 0x123456 ); testColor( c, ui, "selectionInactiveBackground", 0x123456 );
testColor( c, ui, "selectionInactiveForeground", 0x123456 ); testColor( c, ui, "selectionInactiveForeground", 0x123456 );
testColor( c, ui, "selectionBorderColor", 0x123456 ); testColor( c, ui, "selectionBorderColor", 0x123456 );
testInsets( c, ui, "selectionInsets", 1,2,3,4 );
testInteger( c, ui, "selectionArc", 123 );
testBoolean( c, ui, "wideSelection", true ); testBoolean( c, ui, "wideSelection", true );
testBoolean( c, ui, "showCellFocusIndicator", true ); testBoolean( c, ui, "showCellFocusIndicator", true );

View File

@@ -987,6 +987,8 @@ public class TestFlatStyling
ui.applyStyle( "selectionForeground: #fff" ); ui.applyStyle( "selectionForeground: #fff" );
ui.applyStyle( "selectionInactiveBackground: #fff" ); ui.applyStyle( "selectionInactiveBackground: #fff" );
ui.applyStyle( "selectionInactiveForeground: #fff" ); ui.applyStyle( "selectionInactiveForeground: #fff" );
ui.applyStyle( "selectionInsets: 1,2,3,4" );
ui.applyStyle( "selectionArc: 8" );
// FlatTableCellBorder // FlatTableCellBorder
ui.applyStyle( "cellMargins: 1,2,3,4" ); ui.applyStyle( "cellMargins: 1,2,3,4" );

View File

@@ -25,6 +25,8 @@ import javax.swing.*;
import javax.swing.table.*; import javax.swing.table.*;
import javax.swing.tree.*; import javax.swing.tree.*;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.util.ColorFunctions;
import net.miginfocom.swing.*; import net.miginfocom.swing.*;
/** /**
@@ -93,10 +95,12 @@ class DataComponentsPanel
private void rowSelectionChanged() { private void rowSelectionChanged() {
table1.setRowSelectionAllowed( rowSelectionCheckBox.isSelected() ); table1.setRowSelectionAllowed( rowSelectionCheckBox.isSelected() );
roundedSelectionChanged();
} }
private void columnSelectionChanged() { private void columnSelectionChanged() {
table1.setColumnSelectionAllowed( columnSelectionCheckBox.isSelected() ); table1.setColumnSelectionAllowed( columnSelectionCheckBox.isSelected() );
roundedSelectionChanged();
} }
private void showHorizontalLinesChanged() { private void showHorizontalLinesChanged() {
@@ -127,6 +131,28 @@ class DataComponentsPanel
intercellSpacingCheckBox.setSelected( table1.getRowMargin() != 0 ); intercellSpacingCheckBox.setSelected( table1.getRowMargin() != 0 );
} }
private void roundedSelectionChanged() {
String style = null;
if( roundedSelectionCheckBox.isSelected() ) {
style = rowSelectionCheckBox.isSelected()
? "selectionArc: 6; selectionInsets: 0,1,0,1"
: "selectionArc: 6";
}
table1.putClientProperty( FlatClientProperties.STYLE, style );
}
private void alternatingRowsChanged() {
Color alternateRowColor = null;
if( alternatingRowsCheckBox.isSelected() ) {
Color background = table1.getBackground();
alternateRowColor = FlatLaf.isLafDark()
? ColorFunctions.lighten( background, 0.05f )
: ColorFunctions.darken( background, 0.05f );
}
UIManager.put( "Table.alternateRowColor", alternateRowColor );
table1.repaint();
}
@SuppressWarnings( { "unchecked", "rawtypes" } ) @SuppressWarnings( { "unchecked", "rawtypes" } )
private void initComponents() { private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
@@ -151,12 +177,14 @@ class DataComponentsPanel
JScrollPane scrollPane5 = new JScrollPane(); JScrollPane scrollPane5 = new JScrollPane();
table1 = new JTable(); table1 = new JTable();
JPanel tableOptionsPanel = new JPanel(); JPanel tableOptionsPanel = new JPanel();
roundedSelectionCheckBox = new JCheckBox();
showHorizontalLinesCheckBox = new JCheckBox(); showHorizontalLinesCheckBox = new JCheckBox();
showVerticalLinesCheckBox = new JCheckBox(); showVerticalLinesCheckBox = new JCheckBox();
intercellSpacingCheckBox = new JCheckBox(); intercellSpacingCheckBox = new JCheckBox();
redGridColorCheckBox = new JCheckBox(); redGridColorCheckBox = new JCheckBox();
rowSelectionCheckBox = new JCheckBox(); rowSelectionCheckBox = new JCheckBox();
columnSelectionCheckBox = new JCheckBox(); columnSelectionCheckBox = new JCheckBox();
alternatingRowsCheckBox = new JCheckBox();
dndCheckBox = new JCheckBox(); dndCheckBox = new JCheckBox();
JPopupMenu popupMenu2 = new JPopupMenu(); JPopupMenu popupMenu2 = new JPopupMenu();
JMenuItem menuItem3 = new JMenuItem(); JMenuItem menuItem3 = new JMenuItem();
@@ -403,44 +431,56 @@ class DataComponentsPanel
"[]0" + "[]0" +
"[]0" + "[]0" +
"[]0" + "[]0" +
"[]0" +
"[]0" +
"[]0")); "[]0"));
//---- roundedSelectionCheckBox ----
roundedSelectionCheckBox.setText("rounded selection");
roundedSelectionCheckBox.addActionListener(e -> roundedSelectionChanged());
tableOptionsPanel.add(roundedSelectionCheckBox, "cell 0 0");
//---- showHorizontalLinesCheckBox ---- //---- showHorizontalLinesCheckBox ----
showHorizontalLinesCheckBox.setText("show horizontal lines"); showHorizontalLinesCheckBox.setText("show horizontal lines");
showHorizontalLinesCheckBox.addActionListener(e -> showHorizontalLinesChanged()); showHorizontalLinesCheckBox.addActionListener(e -> showHorizontalLinesChanged());
tableOptionsPanel.add(showHorizontalLinesCheckBox, "cell 0 0"); tableOptionsPanel.add(showHorizontalLinesCheckBox, "cell 0 1");
//---- showVerticalLinesCheckBox ---- //---- showVerticalLinesCheckBox ----
showVerticalLinesCheckBox.setText("show vertical lines"); showVerticalLinesCheckBox.setText("show vertical lines");
showVerticalLinesCheckBox.addActionListener(e -> showVerticalLinesChanged()); showVerticalLinesCheckBox.addActionListener(e -> showVerticalLinesChanged());
tableOptionsPanel.add(showVerticalLinesCheckBox, "cell 0 1"); tableOptionsPanel.add(showVerticalLinesCheckBox, "cell 0 2");
//---- intercellSpacingCheckBox ---- //---- intercellSpacingCheckBox ----
intercellSpacingCheckBox.setText("intercell spacing"); intercellSpacingCheckBox.setText("intercell spacing");
intercellSpacingCheckBox.addActionListener(e -> intercellSpacingChanged()); intercellSpacingCheckBox.addActionListener(e -> intercellSpacingChanged());
tableOptionsPanel.add(intercellSpacingCheckBox, "cell 0 2"); tableOptionsPanel.add(intercellSpacingCheckBox, "cell 0 3");
//---- redGridColorCheckBox ---- //---- redGridColorCheckBox ----
redGridColorCheckBox.setText("red grid color"); redGridColorCheckBox.setText("red grid color");
redGridColorCheckBox.addActionListener(e -> redGridColorChanged()); redGridColorCheckBox.addActionListener(e -> redGridColorChanged());
tableOptionsPanel.add(redGridColorCheckBox, "cell 0 3"); tableOptionsPanel.add(redGridColorCheckBox, "cell 0 4");
//---- rowSelectionCheckBox ---- //---- rowSelectionCheckBox ----
rowSelectionCheckBox.setText("row selection"); rowSelectionCheckBox.setText("row selection");
rowSelectionCheckBox.setSelected(true); rowSelectionCheckBox.setSelected(true);
rowSelectionCheckBox.addActionListener(e -> rowSelectionChanged()); rowSelectionCheckBox.addActionListener(e -> rowSelectionChanged());
tableOptionsPanel.add(rowSelectionCheckBox, "cell 0 4"); tableOptionsPanel.add(rowSelectionCheckBox, "cell 0 5");
//---- columnSelectionCheckBox ---- //---- columnSelectionCheckBox ----
columnSelectionCheckBox.setText("column selection"); columnSelectionCheckBox.setText("column selection");
columnSelectionCheckBox.addActionListener(e -> columnSelectionChanged()); columnSelectionCheckBox.addActionListener(e -> columnSelectionChanged());
tableOptionsPanel.add(columnSelectionCheckBox, "cell 0 5"); tableOptionsPanel.add(columnSelectionCheckBox, "cell 0 6");
//---- alternatingRowsCheckBox ----
alternatingRowsCheckBox.setText("alternating rows");
alternatingRowsCheckBox.addActionListener(e -> alternatingRowsChanged());
tableOptionsPanel.add(alternatingRowsCheckBox, "cell 0 7");
//---- dndCheckBox ---- //---- dndCheckBox ----
dndCheckBox.setText("enable drag and drop"); dndCheckBox.setText("enable drag and drop");
dndCheckBox.setMnemonic('D'); dndCheckBox.setMnemonic('D');
dndCheckBox.addActionListener(e -> dndChanged()); dndCheckBox.addActionListener(e -> dndChanged());
tableOptionsPanel.add(dndCheckBox, "cell 0 6"); tableOptionsPanel.add(dndCheckBox, "cell 0 8");
} }
add(tableOptionsPanel, "cell 4 3"); add(tableOptionsPanel, "cell 4 3");
@@ -477,12 +517,14 @@ class DataComponentsPanel
private JTree tree3; private JTree tree3;
private JTree tree2; private JTree tree2;
private JTable table1; private JTable table1;
private JCheckBox roundedSelectionCheckBox;
private JCheckBox showHorizontalLinesCheckBox; private JCheckBox showHorizontalLinesCheckBox;
private JCheckBox showVerticalLinesCheckBox; private JCheckBox showVerticalLinesCheckBox;
private JCheckBox intercellSpacingCheckBox; private JCheckBox intercellSpacingCheckBox;
private JCheckBox redGridColorCheckBox; private JCheckBox redGridColorCheckBox;
private JCheckBox rowSelectionCheckBox; private JCheckBox rowSelectionCheckBox;
private JCheckBox columnSelectionCheckBox; private JCheckBox columnSelectionCheckBox;
private JCheckBox alternatingRowsCheckBox;
private JCheckBox dndCheckBox; private JCheckBox dndCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables

View File

@@ -343,9 +343,19 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3" "$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[]" "$columnConstraints": "[]"
"$rowConstraints": "[]0[]0[]0[]0[]0[]0[]0" "$rowConstraints": "[]0[]0[]0[]0[]0[]0[]0[]0[]0"
} ) { } ) {
name: "tableOptionsPanel" name: "tableOptionsPanel"
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "roundedSelectionCheckBox"
"text": "rounded selection"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "roundedSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showHorizontalLinesCheckBox" name: "showHorizontalLinesCheckBox"
"text": "show horizontal lines" "text": "show horizontal lines"
@@ -354,7 +364,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showHorizontalLinesChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showHorizontalLinesChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0" "value": "cell 0 1"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showVerticalLinesCheckBox" name: "showVerticalLinesCheckBox"
@@ -364,7 +374,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showVerticalLinesChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showVerticalLinesChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1" "value": "cell 0 2"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "intercellSpacingCheckBox" name: "intercellSpacingCheckBox"
@@ -374,7 +384,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "intercellSpacingChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "intercellSpacingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2" "value": "cell 0 3"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "redGridColorCheckBox" name: "redGridColorCheckBox"
@@ -384,7 +394,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "redGridColorChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "redGridColorChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3" "value": "cell 0 4"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "rowSelectionCheckBox" name: "rowSelectionCheckBox"
@@ -395,7 +405,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "rowSelectionChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "rowSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4" "value": "cell 0 5"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "columnSelectionCheckBox" name: "columnSelectionCheckBox"
@@ -405,7 +415,17 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "columnSelectionChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "columnSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5" "value": "cell 0 6"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "alternatingRowsCheckBox"
"text": "alternating rows"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "alternatingRowsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 7"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "dndCheckBox" name: "dndCheckBox"
@@ -416,7 +436,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dndChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dndChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 6" "value": "cell 0 8"
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 3" "value": "cell 4 3"

View File

@@ -47,6 +47,7 @@ import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.icons.FlatMenuArrowIcon; import com.formdev.flatlaf.icons.FlatMenuArrowIcon;
import com.formdev.flatlaf.ui.FlatEmptyBorder; import com.formdev.flatlaf.ui.FlatEmptyBorder;
import com.formdev.flatlaf.ui.FlatListUI; import com.formdev.flatlaf.ui.FlatListUI;
import com.formdev.flatlaf.ui.FlatTableUI;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
import com.jidesoft.swing.*; import com.jidesoft.swing.*;
import com.jidesoft.swing.CheckBoxTreeCellRenderer; import com.jidesoft.swing.CheckBoxTreeCellRenderer;
@@ -164,6 +165,8 @@ public class FlatComponents2Test
JComboBox<String> editableComboBox = new JComboBox<>( months ); JComboBox<String> editableComboBox = new JComboBox<>( months );
editableComboBox.setEditable( true ); editableComboBox.setEditable( true );
cm.getColumn(3).setCellEditor( new DefaultCellEditor( editableComboBox ) ); cm.getColumn(3).setCellEditor( new DefaultCellEditor( editableComboBox ) );
// table.setDefaultRenderer( Object.class, new TestLabelRoundedTableCellRenderer() );
} }
private void expandTree( JTree tree ) { private void expandTree( JTree tree ) {
@@ -229,6 +232,65 @@ public class FlatComponents2Test
FlatLaf.updateUILater(); FlatLaf.updateUILater();
} }
private void roundedSelectionChanged() {
String style = roundedSelectionCheckBox.isSelected() ? "selectionArc: 12; " : "";
int left = leftSelectionInsetsCheckBox.isSelected() ? 2 : 0;
int right = rightSelectionInsetsCheckBox.isSelected() ? 2 : 0;
int top = topSelectionInsetsCheckBox.isSelected() ? 2 : 0;
int bottom = bottomSelectionInsetsCheckBox.isSelected() ? 2 : 0;
if( left > 0 || right > 0 || top > 0 || bottom > 0 )
style += "selectionInsets: " + top + ',' + left + ',' + bottom + ',' + right;
if( style.isEmpty() )
style = null;
list1.putClientProperty( FlatClientProperties.STYLE, style );
list2.putClientProperty( FlatClientProperties.STYLE, style );
tree1.putClientProperty( FlatClientProperties.STYLE, style );
tree2.putClientProperty( FlatClientProperties.STYLE, style );
xTree1.putClientProperty( FlatClientProperties.STYLE, style );
checkBoxTree1.putClientProperty( FlatClientProperties.STYLE, style );
table1.putClientProperty( FlatClientProperties.STYLE, style );
xTable1.putClientProperty( FlatClientProperties.STYLE, style );
xTreeTable1.putClientProperty( FlatClientProperties.STYLE, style );
// initial selection
if( style != null ) {
initSelection( list1 );
initSelection( list2 );
initSelection( tree1 );
initSelection( tree2 );
initSelection( xTree1 );
initSelection( checkBoxTree1 );
initSelection( table1 );
initSelection( xTable1 );
initSelection( xTreeTable1 );
}
if( paintOutsideAlternateRowsCheckBox.isSelected() )
table1ScrollPane.repaint();
}
private static void initSelection( JList<?> list ) {
if( list.isSelectionEmpty() ) {
list.addSelectionInterval( 1, 2 );
list.addSelectionInterval( 5, 5 );
}
}
private static void initSelection( JTree tree ) {
if( tree.isSelectionEmpty() ) {
tree.addSelectionInterval( 1, 2 );
tree.addSelectionInterval( 5, 5 );
}
}
private static void initSelection( JTable table ) {
if( table.getSelectedRowCount() == 0 ) {
table.addRowSelectionInterval( 1, 2 );
table.addRowSelectionInterval( 5, 5 );
}
}
private void dndChanged() { private void dndChanged() {
boolean dnd = dndCheckBox.isSelected(); boolean dnd = dndCheckBox.isSelected();
list1.setDragEnabled( dnd ); list1.setDragEnabled( dnd );
@@ -535,6 +597,12 @@ public class FlatComponents2Test
public void applyComponentOrientation( ComponentOrientation o ) { public void applyComponentOrientation( ComponentOrientation o ) {
super.applyComponentOrientation( o ); super.applyComponentOrientation( o );
// always use left-to-right for options panels
generalOptionsPanel.applyComponentOrientation( ComponentOrientation.LEFT_TO_RIGHT );
listOptionsPanel.applyComponentOrientation( ComponentOrientation.LEFT_TO_RIGHT );
treeOptionsPanel.applyComponentOrientation( ComponentOrientation.LEFT_TO_RIGHT );
tableOptionsPanel.applyComponentOrientation( ComponentOrientation.LEFT_TO_RIGHT );
// swap upper right and left corners (other corners are not used in this app) // swap upper right and left corners (other corners are not used in this app)
Component leftCorner = table1ScrollPane.getCorner( ScrollPaneConstants.UPPER_LEFT_CORNER ); Component leftCorner = table1ScrollPane.getCorner( ScrollPaneConstants.UPPER_LEFT_CORNER );
Component rightCorner = table1ScrollPane.getCorner( ScrollPaneConstants.UPPER_RIGHT_CORNER ); Component rightCorner = table1ScrollPane.getCorner( ScrollPaneConstants.UPPER_RIGHT_CORNER );
@@ -596,16 +664,22 @@ public class FlatComponents2Test
JLabel label2 = new JLabel(); JLabel label2 = new JLabel();
xTreeTable1ScrollPane = new JScrollPane(); xTreeTable1ScrollPane = new JScrollPane();
xTreeTable1 = new JXTreeTable(); xTreeTable1 = new JXTreeTable();
JPanel panel5 = new JPanel(); generalOptionsPanel = new JPanel();
roundedSelectionCheckBox = new JCheckBox();
JLabel label6 = new JLabel();
topSelectionInsetsCheckBox = new JCheckBox();
bottomSelectionInsetsCheckBox = new JCheckBox();
leftSelectionInsetsCheckBox = new JCheckBox();
rightSelectionInsetsCheckBox = new JCheckBox();
dndCheckBox = new JCheckBox(); dndCheckBox = new JCheckBox();
JPanel panel6 = new JPanel(); listOptionsPanel = new JPanel();
JLabel listRendererLabel = new JLabel(); JLabel listRendererLabel = new JLabel();
listRendererComboBox = new JComboBox<>(); listRendererComboBox = new JComboBox<>();
JLabel listLayoutOrientationLabel = new JLabel(); JLabel listLayoutOrientationLabel = new JLabel();
listLayoutOrientationField = new JComboBox<>(); listLayoutOrientationField = new JComboBox<>();
JLabel listVisibleRowCountLabel = new JLabel(); JLabel listVisibleRowCountLabel = new JLabel();
listVisibleRowCountSpinner = new JSpinner(); listVisibleRowCountSpinner = new JSpinner();
JPanel treeOptionsPanel = new JPanel(); treeOptionsPanel = new JPanel();
JLabel treeRendererLabel = new JLabel(); JLabel treeRendererLabel = new JLabel();
treeRendererComboBox = new JComboBox<>(); treeRendererComboBox = new JComboBox<>();
treeWideSelectionCheckBox = new JCheckBox(); treeWideSelectionCheckBox = new JCheckBox();
@@ -614,7 +688,7 @@ public class FlatComponents2Test
treeRedLinesCheckBox = new JCheckBox(); treeRedLinesCheckBox = new JCheckBox();
treeEditableCheckBox = new JCheckBox(); treeEditableCheckBox = new JCheckBox();
treeShowDefaultIconsCheckBox = new JCheckBox(); treeShowDefaultIconsCheckBox = new JCheckBox();
JPanel tableOptionsPanel = new JPanel(); tableOptionsPanel = new JPanel();
JLabel autoResizeModeLabel = new JLabel(); JLabel autoResizeModeLabel = new JLabel();
autoResizeModeField = new JComboBox<>(); autoResizeModeField = new JComboBox<>();
JLabel sortIconPositionLabel = new JLabel(); JLabel sortIconPositionLabel = new JLabel();
@@ -872,30 +946,68 @@ public class FlatComponents2Test
} }
add(xTreeTable1ScrollPane, "cell 4 3 2 1"); add(xTreeTable1ScrollPane, "cell 4 3 2 1");
//======== panel5 ======== //======== generalOptionsPanel ========
{ {
panel5.setBorder(new TitledBorder("General Control")); generalOptionsPanel.setBorder(new TitledBorder("General Control"));
panel5.putClientProperty("FlatLaf.internal.testing.ignore", true); generalOptionsPanel.putClientProperty("FlatLaf.internal.testing.ignore", true);
panel5.setLayout(new MigLayout( generalOptionsPanel.setLayout(new MigLayout(
"hidemode 3", "insets 8,hidemode 3",
// columns // columns
"[fill]", "[left]",
// rows // rows
"[]" +
"[]0" +
"[]0" +
"[]rel" +
"[]")); "[]"));
//---- roundedSelectionCheckBox ----
roundedSelectionCheckBox.setText("rounded selection");
roundedSelectionCheckBox.setMnemonic('D');
roundedSelectionCheckBox.addActionListener(e -> roundedSelectionChanged());
generalOptionsPanel.add(roundedSelectionCheckBox, "cell 0 0");
//---- label6 ----
label6.setText("Selection insets:");
generalOptionsPanel.add(label6, "cell 0 1");
//---- topSelectionInsetsCheckBox ----
topSelectionInsetsCheckBox.setText("top");
topSelectionInsetsCheckBox.setMnemonic('D');
topSelectionInsetsCheckBox.addActionListener(e -> roundedSelectionChanged());
generalOptionsPanel.add(topSelectionInsetsCheckBox, "cell 0 2,gapx ind");
//---- bottomSelectionInsetsCheckBox ----
bottomSelectionInsetsCheckBox.setText("bottom");
bottomSelectionInsetsCheckBox.setMnemonic('D');
bottomSelectionInsetsCheckBox.addActionListener(e -> roundedSelectionChanged());
generalOptionsPanel.add(bottomSelectionInsetsCheckBox, "cell 0 2");
//---- leftSelectionInsetsCheckBox ----
leftSelectionInsetsCheckBox.setText("left");
leftSelectionInsetsCheckBox.setMnemonic('D');
leftSelectionInsetsCheckBox.addActionListener(e -> roundedSelectionChanged());
generalOptionsPanel.add(leftSelectionInsetsCheckBox, "cell 0 3,gapx ind");
//---- rightSelectionInsetsCheckBox ----
rightSelectionInsetsCheckBox.setText("right");
rightSelectionInsetsCheckBox.setMnemonic('D');
rightSelectionInsetsCheckBox.addActionListener(e -> roundedSelectionChanged());
generalOptionsPanel.add(rightSelectionInsetsCheckBox, "cell 0 3");
//---- dndCheckBox ---- //---- dndCheckBox ----
dndCheckBox.setText("drag and drop"); dndCheckBox.setText("drag and drop");
dndCheckBox.setMnemonic('D'); dndCheckBox.setMnemonic('D');
dndCheckBox.addActionListener(e -> dndChanged()); dndCheckBox.addActionListener(e -> dndChanged());
panel5.add(dndCheckBox, "cell 0 0"); generalOptionsPanel.add(dndCheckBox, "cell 0 4");
} }
add(panel5, "cell 0 4 4 1"); add(generalOptionsPanel, "cell 0 4 4 1");
//======== panel6 ======== //======== listOptionsPanel ========
{ {
panel6.setBorder(new TitledBorder("JList Control")); listOptionsPanel.setBorder(new TitledBorder("JList Control"));
panel6.setLayout(new MigLayout( listOptionsPanel.setLayout(new MigLayout(
"hidemode 3", "insets 8,hidemode 3",
// columns // columns
"[fill]" + "[fill]" +
"[fill]", "[fill]",
@@ -906,7 +1018,7 @@ public class FlatComponents2Test
//---- listRendererLabel ---- //---- listRendererLabel ----
listRendererLabel.setText("Renderer:"); listRendererLabel.setText("Renderer:");
panel6.add(listRendererLabel, "cell 0 0"); listOptionsPanel.add(listRendererLabel, "cell 0 0");
//---- listRendererComboBox ---- //---- listRendererComboBox ----
listRendererComboBox.setModel(new DefaultComboBoxModel<>(new String[] { listRendererComboBox.setModel(new DefaultComboBoxModel<>(new String[] {
@@ -916,11 +1028,11 @@ public class FlatComponents2Test
"labelRounded" "labelRounded"
})); }));
listRendererComboBox.addActionListener(e -> listRendererChanged()); listRendererComboBox.addActionListener(e -> listRendererChanged());
panel6.add(listRendererComboBox, "cell 1 0"); listOptionsPanel.add(listRendererComboBox, "cell 1 0");
//---- listLayoutOrientationLabel ---- //---- listLayoutOrientationLabel ----
listLayoutOrientationLabel.setText("Orientation:"); listLayoutOrientationLabel.setText("Orientation:");
panel6.add(listLayoutOrientationLabel, "cell 0 1"); listOptionsPanel.add(listLayoutOrientationLabel, "cell 0 1");
//---- listLayoutOrientationField ---- //---- listLayoutOrientationField ----
listLayoutOrientationField.setModel(new DefaultComboBoxModel<>(new String[] { listLayoutOrientationField.setModel(new DefaultComboBoxModel<>(new String[] {
@@ -929,25 +1041,25 @@ public class FlatComponents2Test
"horzontal wrap" "horzontal wrap"
})); }));
listLayoutOrientationField.addActionListener(e -> listLayoutOrientationChanged()); listLayoutOrientationField.addActionListener(e -> listLayoutOrientationChanged());
panel6.add(listLayoutOrientationField, "cell 1 1"); listOptionsPanel.add(listLayoutOrientationField, "cell 1 1");
//---- listVisibleRowCountLabel ---- //---- listVisibleRowCountLabel ----
listVisibleRowCountLabel.setText("Visible row count:"); listVisibleRowCountLabel.setText("Visible row count:");
panel6.add(listVisibleRowCountLabel, "cell 0 2"); listOptionsPanel.add(listVisibleRowCountLabel, "cell 0 2");
//---- listVisibleRowCountSpinner ---- //---- listVisibleRowCountSpinner ----
listVisibleRowCountSpinner.setModel(new SpinnerNumberModel(8, 0, null, 1)); listVisibleRowCountSpinner.setModel(new SpinnerNumberModel(8, 0, null, 1));
listVisibleRowCountSpinner.addChangeListener(e -> listVisibleRowCountChanged()); listVisibleRowCountSpinner.addChangeListener(e -> listVisibleRowCountChanged());
panel6.add(listVisibleRowCountSpinner, "cell 1 2"); listOptionsPanel.add(listVisibleRowCountSpinner, "cell 1 2");
} }
add(panel6, "cell 0 4 4 1"); add(listOptionsPanel, "cell 0 4 4 1");
//======== treeOptionsPanel ======== //======== treeOptionsPanel ========
{ {
treeOptionsPanel.setBorder(new TitledBorder("JTree Control")); treeOptionsPanel.setBorder(new TitledBorder("JTree Control"));
treeOptionsPanel.putClientProperty("FlatLaf.internal.testing.ignore", true); treeOptionsPanel.putClientProperty("FlatLaf.internal.testing.ignore", true);
treeOptionsPanel.setLayout(new MigLayout( treeOptionsPanel.setLayout(new MigLayout(
"hidemode 3", "insets 8,hidemode 3",
// columns // columns
"[left]", "[left]",
// rows // rows
@@ -1014,7 +1126,7 @@ public class FlatComponents2Test
tableOptionsPanel.setBorder(new TitledBorder("JTable Control")); tableOptionsPanel.setBorder(new TitledBorder("JTable Control"));
tableOptionsPanel.putClientProperty("FlatLaf.internal.testing.ignore", true); tableOptionsPanel.putClientProperty("FlatLaf.internal.testing.ignore", true);
tableOptionsPanel.setLayout(new MigLayout( tableOptionsPanel.setLayout(new MigLayout(
"hidemode 3", "insets 8,hidemode 3",
// columns // columns
"[]" + "[]" +
"[fill]" + "[fill]" +
@@ -1132,10 +1244,18 @@ public class FlatComponents2Test
private CheckBoxTree checkBoxTree1; private CheckBoxTree checkBoxTree1;
private JScrollPane xTreeTable1ScrollPane; private JScrollPane xTreeTable1ScrollPane;
private JXTreeTable xTreeTable1; private JXTreeTable xTreeTable1;
private JPanel generalOptionsPanel;
private JCheckBox roundedSelectionCheckBox;
private JCheckBox topSelectionInsetsCheckBox;
private JCheckBox bottomSelectionInsetsCheckBox;
private JCheckBox leftSelectionInsetsCheckBox;
private JCheckBox rightSelectionInsetsCheckBox;
private JCheckBox dndCheckBox; private JCheckBox dndCheckBox;
private JPanel listOptionsPanel;
private JComboBox<String> listRendererComboBox; private JComboBox<String> listRendererComboBox;
private JComboBox<String> listLayoutOrientationField; private JComboBox<String> listLayoutOrientationField;
private JSpinner listVisibleRowCountSpinner; private JSpinner listVisibleRowCountSpinner;
private JPanel treeOptionsPanel;
private JComboBox<String> treeRendererComboBox; private JComboBox<String> treeRendererComboBox;
private JCheckBox treeWideSelectionCheckBox; private JCheckBox treeWideSelectionCheckBox;
private JCheckBox treePaintSelectionCheckBox; private JCheckBox treePaintSelectionCheckBox;
@@ -1143,6 +1263,7 @@ public class FlatComponents2Test
private JCheckBox treeRedLinesCheckBox; private JCheckBox treeRedLinesCheckBox;
private JCheckBox treeEditableCheckBox; private JCheckBox treeEditableCheckBox;
private JCheckBox treeShowDefaultIconsCheckBox; private JCheckBox treeShowDefaultIconsCheckBox;
private JPanel tableOptionsPanel;
private JComboBox<String> autoResizeModeField; private JComboBox<String> autoResizeModeField;
private JComboBox<String> sortIconPositionComboBox; private JComboBox<String> sortIconPositionComboBox;
private JCheckBox showHorizontalLinesCheckBox; private JCheckBox showHorizontalLinesCheckBox;
@@ -1683,4 +1804,46 @@ public class FlatComponents2Test
return this; return this;
} }
} }
//---- class TestLabelRoundedTableCellRenderer ----------------------------
@SuppressWarnings( "unused" )
private static class TestLabelRoundedTableCellRenderer
extends JLabel
implements TableCellRenderer
{
private JTable table;
private int row;
private int column;
private boolean isSelected;
TestLabelRoundedTableCellRenderer() {
setBorder( new FlatEmptyBorder( 1, 6, 1, 6 ) );
}
@Override
public Component getTableCellRendererComponent( JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column )
{
this.table = table;
this.row = row;
this.column = column;
this.isSelected = isSelected;
setText( String.valueOf( value ) );
setBackground( isSelected ? Color.green : table.getBackground() );
setForeground( isSelected ? Color.blue : table.getForeground() );
return this;
}
@Override
protected void paintComponent( Graphics g ) {
if( isSelected ) {
g.setColor( getBackground() );
FlatTableUI.paintCellSelection( table, g, row, column, 0, 0, getWidth(), getHeight() );
}
super.paintComponent( g );
}
}
} }

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "8.0.0.0.194" Java: "17.0.2" encoding: "UTF-8" JFDML JFormDesigner: "8.2.2.0.9999" Java: "21.0.1" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -297,13 +297,77 @@ new FormModel {
"value": "cell 4 3 2 1" "value": "cell 4 3 2 1"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3" "$layoutConstraints": "insets 8,hidemode 3"
"$columnConstraints": "[fill]" "$columnConstraints": "[left]"
"$rowConstraints": "[]" "$rowConstraints": "[][]0[]0[]rel[]"
} ) { } ) {
name: "panel5" name: "generalOptionsPanel"
"border": new javax.swing.border.TitledBorder( "General Control" ) "border": new javax.swing.border.TitledBorder( "General Control" )
"$client.FlatLaf.internal.testing.ignore": true "$client.FlatLaf.internal.testing.ignore": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "roundedSelectionCheckBox"
"text": "rounded selection"
"mnemonic": 68
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "roundedSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label6"
"text": "Selection insets:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "topSelectionInsetsCheckBox"
"text": "top"
"mnemonic": 68
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "roundedSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2,gapx ind"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "bottomSelectionInsetsCheckBox"
"text": "bottom"
"mnemonic": 68
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "roundedSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leftSelectionInsetsCheckBox"
"text": "left"
"mnemonic": 68
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "roundedSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3,gapx ind"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "rightSelectionInsetsCheckBox"
"text": "right"
"mnemonic": 68
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "roundedSelectionChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "dndCheckBox" name: "dndCheckBox"
"text": "drag and drop" "text": "drag and drop"
@@ -313,18 +377,21 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dndChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dndChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0" "value": "cell 0 4"
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4 4 1" "value": "cell 0 4 4 1"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3" "$layoutConstraints": "insets 8,hidemode 3"
"$columnConstraints": "[fill][fill]" "$columnConstraints": "[fill][fill]"
"$rowConstraints": "[][][]" "$rowConstraints": "[][][]"
} ) { } ) {
name: "panel6" name: "listOptionsPanel"
"border": new javax.swing.border.TitledBorder( "JList Control" ) "border": new javax.swing.border.TitledBorder( "JList Control" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "listRendererLabel" name: "listRendererLabel"
"text": "Renderer:" "text": "Renderer:"
@@ -392,13 +459,16 @@ new FormModel {
"value": "cell 0 4 4 1" "value": "cell 0 4 4 1"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3" "$layoutConstraints": "insets 8,hidemode 3"
"$columnConstraints": "[left]" "$columnConstraints": "[left]"
"$rowConstraints": "[][]0[]0[]0[]" "$rowConstraints": "[][]0[]0[]0[]"
} ) { } ) {
name: "treeOptionsPanel" name: "treeOptionsPanel"
"border": new javax.swing.border.TitledBorder( "JTree Control" ) "border": new javax.swing.border.TitledBorder( "JTree Control" )
"$client.FlatLaf.internal.testing.ignore": true "$client.FlatLaf.internal.testing.ignore": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "treeRendererLabel" name: "treeRendererLabel"
"text": "Renderer:" "text": "Renderer:"
@@ -491,13 +561,16 @@ new FormModel {
"value": "cell 0 4 4 1" "value": "cell 0 4 4 1"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3" "$layoutConstraints": "insets 8,hidemode 3"
"$columnConstraints": "[][fill][fill]" "$columnConstraints": "[][fill][fill]"
"$rowConstraints": "[][]0[]0[]0[]0" "$rowConstraints": "[][]0[]0[]0[]0"
} ) { } ) {
name: "tableOptionsPanel" name: "tableOptionsPanel"
"border": new javax.swing.border.TitledBorder( "JTable Control" ) "border": new javax.swing.border.TitledBorder( "JTable Control" )
"$client.FlatLaf.internal.testing.ignore": true "$client.FlatLaf.internal.testing.ignore": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "autoResizeModeLabel" name: "autoResizeModeLabel"
"text": "Auto resize mode:" "text": "Auto resize mode:"