lemon
3 months ago
25 changed files with 431 additions and 204 deletions
@ -0,0 +1,107 @@
|
||||
package com.fine.theme.light.ui; |
||||
|
||||
import com.fine.theme.utils.FineUIScale; |
||||
import com.fine.theme.utils.FineUIStyle; |
||||
import com.formdev.flatlaf.ui.FlatTableHeaderUI; |
||||
import com.fr.stable.StringUtils; |
||||
import sun.swing.DefaultLookup; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JTable; |
||||
import javax.swing.SwingConstants; |
||||
import javax.swing.UIManager; |
||||
import javax.swing.border.Border; |
||||
import javax.swing.plaf.ComponentUI; |
||||
import javax.swing.plaf.UIResource; |
||||
import javax.swing.table.DefaultTableCellRenderer; |
||||
import javax.swing.table.JTableHeader; |
||||
import java.awt.Component; |
||||
import java.awt.Dimension; |
||||
import java.awt.Graphics; |
||||
|
||||
/** |
||||
* 应用于 JTable 的UI |
||||
* |
||||
* @author lemon |
||||
* @since |
||||
* Created on |
||||
*/ |
||||
public class FineTableHeaderUI extends FlatTableHeaderUI { |
||||
|
||||
@Override |
||||
public void installUI(JComponent c) { |
||||
super.installUI(c); |
||||
JTableHeader header = (JTableHeader) c; |
||||
header.setDefaultRenderer(new TableHeaderRenderer()); |
||||
JTable table = header.getTable(); |
||||
|
||||
FineUIStyle.setStyle(table, FineUIStyle.DEFAULT_TABLE); |
||||
table.getTableHeader().getTable().setDefaultRenderer(Object.class, new TableRenderer()); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void paint(Graphics g, JComponent c) { |
||||
super.paint(g, c); |
||||
} |
||||
|
||||
/** |
||||
* 表头 render |
||||
*/ |
||||
public static class TableHeaderRenderer extends DefaultTableCellRenderer implements UIResource { |
||||
public TableHeaderRenderer() { |
||||
setPreferredSize(new Dimension(this.getWidth(), FineUIScale.scale(24))); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||
Border var13 = null; |
||||
if (hasFocus) { |
||||
var13 = DefaultLookup.getBorder(this, this.ui, "TableHeader.focusCellBorder"); |
||||
} |
||||
|
||||
if (var13 == null) { |
||||
var13 = DefaultLookup.getBorder(this, this.ui, "TableHeader.cellBorder"); |
||||
} |
||||
|
||||
this.setText(value == null ? "" : value.toString()); |
||||
this.setHorizontalAlignment(SwingConstants.LEFT); |
||||
this.setBorder(var13); |
||||
return this; |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* UI |
||||
* @param c |
||||
* @return |
||||
*/ |
||||
public static ComponentUI createUI(JComponent c) { |
||||
return new FineTableHeaderUI(); |
||||
} |
||||
|
||||
/** |
||||
* 表身 render |
||||
*/ |
||||
public static class TableRenderer extends DefaultTableCellRenderer { |
||||
public TableRenderer() { |
||||
setHorizontalAlignment(SwingConstants.LEFT); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||
if (column == table.getColumnCount() - 1) { |
||||
this.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager.getColor("defaultBorderColor")), |
||||
UIManager.getBorder("Table.cellNoFocusBorder"))); |
||||
} else { |
||||
this.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, UIManager.getColor("defaultBorderColor")), |
||||
UIManager.getBorder("Table.cellNoFocusBorder"))); |
||||
} |
||||
setBackground(UIManager.getColor("Table.background")); |
||||
setText(value == null ? StringUtils.BLANK : String.valueOf(value)); |
||||
return this; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,53 @@
|
||||
package com.fine.theme.light.ui; |
||||
|
||||
import com.formdev.flatlaf.ui.FlatScrollBarUI; |
||||
|
||||
import javax.swing.JComponent; |
||||
import javax.swing.JTable; |
||||
import javax.swing.UIManager; |
||||
import java.awt.BasicStroke; |
||||
import java.awt.Graphics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.Rectangle; |
||||
|
||||
/** |
||||
* 应用于 JTable 的垂直滚动条UI |
||||
* |
||||
* @author lemon |
||||
* @since |
||||
* Created on 2024/08/11 |
||||
*/ |
||||
public class FineTableScrollBarPaneUI extends FlatScrollBarUI { |
||||
|
||||
private final JTable table; |
||||
|
||||
public FineTableScrollBarPaneUI(JTable table) { |
||||
this.table = table; |
||||
} |
||||
|
||||
@Override |
||||
protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) { |
||||
super.paintTrack(g, c, trackBounds); |
||||
// 获取表头的高度
|
||||
int gridLineThickness = 1; |
||||
Rectangle headerRect = table.getTableHeader().getBounds(); |
||||
int headerBottomY = headerRect.y + headerRect.height - gridLineThickness; |
||||
|
||||
// 在滚动条上限(表头的下边框位置)绘制一条线
|
||||
Graphics2D g2d = (Graphics2D) g; |
||||
g2d.setColor(UIManager.getColor("defaultBorderColor")); // 设置线条颜色
|
||||
g2d.setStroke(new BasicStroke(1)); // 设置线条宽度
|
||||
g2d.drawLine(trackBounds.x, headerBottomY, trackBounds.x + trackBounds.width, headerBottomY); |
||||
} |
||||
|
||||
@Override |
||||
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { |
||||
// 确保滚动条滑块不会超过表头区域
|
||||
Rectangle headerRect = table.getTableHeader().getBounds(); |
||||
int headerHeight = headerRect.height; |
||||
thumbBounds.y = Math.max(thumbBounds.y, headerHeight); |
||||
|
||||
super.paintThumb(g, c, thumbBounds); |
||||
} |
||||
|
||||
} |
@ -1 +1 @@
|
||||
package com.fr.design.mainframe;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.iscrollbar.UIScrollBar;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
/**
* Author : daisy
* Date: 13-9-11
* Time: 上午10:14
*/
public class DottedLine extends JPanel {
public static final int HEIGHT = 3;
private static final int BLUE_WIDTH = 12;//蓝色线长度,白色线长度是其半
private int direction = UIScrollBar.HORIZONTAL;
public DottedLine(int direction, int width) {
//水平方向的虚线框
if (direction == UIScrollBar.HORIZONTAL) {
this.setPreferredSize(new Dimension(width, HEIGHT));
} else {
this.setPreferredSize(new Dimension(HEIGHT, width));
}
this.direction = direction;
this.setBackground(new Color(255, 255, 255));//设置白色背景
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
//如果是水平方向的
if (direction == UIScrollBar.HORIZONTAL) {
paintHorizontal(g2d);
} else {
paintVertical(g2d);
}
}
private void paintHorizontal(Graphics2D g2d) {
int totalWidth = getWidth();
int paintX = 0;
while (paintX < totalWidth) {
int endX = paintX + BLUE_WIDTH;
if (endX > totalWidth) {
endX = totalWidth;
}
int[] x = new int[]{paintX, endX, endX, paintX, paintX};
int[] y = new int[]{0, 0, HEIGHT, HEIGHT, 0};
paintBlueArea(g2d, x, y);
paintX += BLUE_WIDTH + BLUE_WIDTH / 2;
}
}
private void paintVertical(Graphics2D g2d) {
int totalHeight = getHeight();
int paintY = 0;
while (paintY < totalHeight) {
int endY = paintY + BLUE_WIDTH;
if (endY > totalHeight) {
endY = totalHeight;
}
int[] x = new int[]{0, HEIGHT, HEIGHT, 0, 0};
int[] y = new int[]{paintY, paintY, endY, endY, paintY};
paintBlueArea(g2d, x, y);
paintY += BLUE_WIDTH + BLUE_WIDTH / 2;
}
}
private void paintBlueArea(Graphics2D g2d, int[] x, int[] y) {
g2d.setPaint(UIConstants.DOTTED_LINE_COLOR);
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length);
generalPath.moveTo(x[0], y[0]);
for (int index = 1; index < x.length; index++) {
generalPath.lineTo(x[index], y[index]);
}
generalPath.closePath();
g2d.fill(generalPath);
}
} |
||||
package com.fr.design.mainframe;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.iscrollbar.UIScrollBar;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
/**
* Author : daisy
* Date: 13-9-11
* Time: 上午10:14
*/
public class DottedLine extends JPanel {
public static final int HEIGHT = 3;
private static final int BLUE_WIDTH = 12;//蓝色线长度,白色线长度是其半
private int direction = UIScrollBar.HORIZONTAL;
public DottedLine(int direction, int width) {
//水平方向的虚线框
if (direction == UIScrollBar.HORIZONTAL) {
this.setPreferredSize(new Dimension(width, HEIGHT));
} else {
this.setPreferredSize(new Dimension(HEIGHT, width));
}
this.direction = direction;
this.setBackground(new Color(255, 255, 255));//设置白色背景
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
//如果是水平方向的
if (direction == UIScrollBar.HORIZONTAL) {
paintHorizontal(g2d);
} else {
paintVertical(g2d);
}
}
private void paintHorizontal(Graphics2D g2d) {
int totalWidth = getWidth();
int paintX = 0;
while (paintX < totalWidth) {
int endX = paintX + BLUE_WIDTH;
if (endX > totalWidth) {
endX = totalWidth;
}
int[] x = new int[]{paintX, endX, endX, paintX, paintX};
int[] y = new int[]{0, 0, HEIGHT, HEIGHT, 0};
paintBlueArea(g2d, x, y);
paintX += BLUE_WIDTH + BLUE_WIDTH / 2;
}
}
private void paintVertical(Graphics2D g2d) {
int totalHeight = getHeight();
int paintY = 0;
while (paintY < totalHeight) {
int endY = paintY + BLUE_WIDTH;
if (endY > totalHeight) {
endY = totalHeight;
}
int[] x = new int[]{0, HEIGHT, HEIGHT, 0, 0};
int[] y = new int[]{paintY, paintY, endY, endY, paintY};
paintBlueArea(g2d, x, y);
paintY += BLUE_WIDTH + BLUE_WIDTH / 2;
}
}
private void paintBlueArea(Graphics2D g2d, int[] x, int[] y) {
g2d.setPaint(FlatUIUtils.getUIColor("DottedLine.defaultColor", new Color(37,118,239,1)));
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length);
generalPath.moveTo(x[0], y[0]);
for (int index = 1; index < x.length; index++) {
generalPath.lineTo(x[index], y[index]);
}
generalPath.closePath();
g2d.fill(generalPath);
}
} |
@ -0,0 +1,111 @@
|
||||
package com.fr.design.gui.storybook.components; |
||||
|
||||
import com.fine.theme.light.ui.FineRoundBorder; |
||||
import com.fine.theme.light.ui.FineTableHeaderUI; |
||||
import com.fine.theme.light.ui.FineTableScrollBarPaneUI; |
||||
import com.fr.design.gui.icontainer.UIScrollPane; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.storybook.StoryBoard; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JCheckBox; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JLabel; |
||||
import javax.swing.JTable; |
||||
import javax.swing.UIManager; |
||||
import javax.swing.plaf.UIResource; |
||||
import javax.swing.table.DefaultTableModel; |
||||
import javax.swing.table.TableCellRenderer; |
||||
|
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Dimension; |
||||
|
||||
import static com.fine.swing.ui.layout.Layouts.cell; |
||||
import static com.fine.swing.ui.layout.Layouts.column; |
||||
|
||||
public class TableStoryBoard extends StoryBoard { |
||||
public TableStoryBoard() { |
||||
super("表格"); |
||||
|
||||
DefaultTableModel model1 = new DefaultTableModel(new Object[][] { |
||||
{"1", "Alice", "Female", "Engineering"}, |
||||
{"2", "Bob", "Male", "Marketing"}, |
||||
{"3", "Carol", "Female", "Design"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"}, |
||||
{"4", "Dave", "Male", "Finance"} |
||||
}, new String[] {"ID", "Name", "Gender", "Department"}); |
||||
JTable table1 = new JTable(model1); |
||||
table1.getTableHeader().setUI(new FineTableHeaderUI()); |
||||
|
||||
DefaultTableModel model2 = new DefaultTableModel(new Object[][] { |
||||
{"1", "Alice", "Female", "Engineering"}, |
||||
{"2", "Bob", "Male", "Marketing"}, |
||||
{"3", "Carol", "Female", "Design"}, |
||||
{"4", "Dave", "Male", "Finance"} |
||||
}, new String[] {"ID", "Name", "Gender", "Department"}); |
||||
JTable table2 = new JTable(model2); |
||||
table2.getTableHeader().setUI(new FineTableHeaderUI()); |
||||
|
||||
DefaultTableModel model3 = new DefaultTableModel(new Object[][] { |
||||
{false, "1", "Alice", "Female", "Engineering"}, |
||||
{false, "2", "Bob", "Male", "Marketing"}, |
||||
{false, "3", "Carol", "Female", "Design"}, |
||||
{false, "4", "Dave", "Male", "Finance"} |
||||
}, new String[] {"选中", "ID", "Name", "Gender", "Department"}) { |
||||
private static final long serialVersionUID = 1L; |
||||
Class<?>[] types = new Class<?>[]{Boolean.class, UILabel.class, UILabel.class, UILabel.class, UILabel.class}; |
||||
|
||||
public Class<?> getColumnClass(int columnIndex) { |
||||
return types[columnIndex]; |
||||
} |
||||
}; |
||||
JTable table3 = new JTable(model3); |
||||
table3.getTableHeader().setUI(new FineTableHeaderUI()); |
||||
table3.getTableHeader().getColumnModel().getColumn(0).setCellRenderer(new BooleanRenderer()); |
||||
|
||||
add(column(20, cell(new UIScrollPane(table1)).with(this::setFixSize).with(it -> it.getVerticalScrollBar().setUI(new FineTableScrollBarPaneUI(table1))), |
||||
cell(new UIScrollPane(table2)).with(this::setFixSize), |
||||
cell(new UIScrollPane(table3)).with(this::setFixSize)).getComponent()); |
||||
} |
||||
|
||||
|
||||
private void setFixSize(JComponent component) { |
||||
component.setPreferredSize(new Dimension(component.getWidth(), 150)); |
||||
component.setBorder(new FineRoundBorder()); |
||||
} |
||||
|
||||
public static class BooleanRenderer extends JCheckBox implements TableCellRenderer, UIResource { |
||||
public BooleanRenderer() { |
||||
super(); |
||||
setHorizontalAlignment(JLabel.CENTER); |
||||
setOpaque(false); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellRendererComponent(JTable table, Object value, |
||||
boolean isSelected, boolean hasFocus, int row, int column) { |
||||
setSelected((value != null && ((Boolean) value).booleanValue())); |
||||
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, UIManager.getColor("defaultBorderColor"))); |
||||
setBackground(Color.WHITE); |
||||
return this; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue