Scale the interface fractionally on Linux
Java2D on X11 (and so under XWayland) truncates its scale to a whole number, drawing 150 % at 100 %. On Linux, pin Java2D to 1 and hand the full factor to FlatLaf, taken from XSETTINGS Xft/DPI, KWin's Xwayland scale or GDK_SCALE, or chosen in Options → Design. The client's own sizes now go through UIScale: borders, gaps, dialog and row sizes, icons (rendered at the scaled size, so they stay crisp), custom-painted components and font sizes in the HTML views. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
package com.ts3client.ui;
|
||||
|
||||
import com.formdev.flatlaf.util.ScaledEmptyBorder;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
import com.ts3client.config.Settings;
|
||||
import com.ts3client.sound.NotificationSettings;
|
||||
import com.ts3client.sound.SoundEvent;
|
||||
import com.ts3client.sound.SoundNotifier;
|
||||
import com.ts3client.sound.SoundPack;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
@@ -79,7 +80,7 @@ final class NotificationsPanel extends JPanel {
|
||||
private final EventTableModel tableModel = new EventTableModel();
|
||||
|
||||
NotificationsPanel(Settings settings, SoundNotifier sounds) {
|
||||
super(new BorderLayout(0, 8));
|
||||
super(new BorderLayout(0, UIScale.scale(8)));
|
||||
this.settings = settings;
|
||||
this.sounds = sounds;
|
||||
this.working = settings.notifications.copy();
|
||||
@@ -91,7 +92,7 @@ final class NotificationsPanel extends JPanel {
|
||||
buildRows();
|
||||
this.table = buildTable();
|
||||
|
||||
setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
||||
setBorder(new ScaledEmptyBorder(12, 12, 12, 12));
|
||||
add(buildHeader(), BorderLayout.NORTH);
|
||||
add(new JScrollPane(table), BorderLayout.CENTER);
|
||||
add(buildFooter(), BorderLayout.SOUTH);
|
||||
@@ -122,7 +123,7 @@ final class NotificationsPanel extends JPanel {
|
||||
private JComponent buildHeader() {
|
||||
JPanel p = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.insets = new Insets(2, 2, 2, 2);
|
||||
c.insets = UIScale.scale(new Insets(2, 2, 2, 2));
|
||||
c.anchor = GridBagConstraints.WEST;
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
@@ -132,7 +133,7 @@ final class NotificationsPanel extends JPanel {
|
||||
test.setToolTipText("Play this pack's test sound");
|
||||
test.addActionListener(e -> sounds.preview(SoundEvent.SPECIAL_SOUND_TEST));
|
||||
|
||||
JPanel packRow = new JPanel(new BorderLayout(6, 0));
|
||||
JPanel packRow = new JPanel(new BorderLayout(UIScale.scale(6), 0));
|
||||
packRow.add(packCombo, BorderLayout.CENTER);
|
||||
packRow.add(test, BorderLayout.EAST);
|
||||
|
||||
@@ -146,7 +147,7 @@ final class NotificationsPanel extends JPanel {
|
||||
volume.setToolTipText("Volume of the notification sounds");
|
||||
addRow(p, c, row++, new JLabel("Sound volume:"), volume);
|
||||
|
||||
JPanel dirRow = new JPanel(new BorderLayout(6, 0));
|
||||
JPanel dirRow = new JPanel(new BorderLayout(UIScale.scale(6), 0));
|
||||
JButton browse = new JButton("Browse…");
|
||||
browse.addActionListener(e -> browseForPackFolder());
|
||||
dirRow.add(packDirField, BorderLayout.CENTER);
|
||||
@@ -157,10 +158,10 @@ final class NotificationsPanel extends JPanel {
|
||||
}
|
||||
|
||||
private JComponent buildFooter() {
|
||||
JPanel p = new JPanel(new BorderLayout(6, 0));
|
||||
JPanel p = new JPanel(new BorderLayout(UIScale.scale(6), 0));
|
||||
JLabel hint = new JLabel("<html><b>Bold</b> actions are important: they are still played "
|
||||
+ "while your speakers are muted.</html>");
|
||||
hint.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
|
||||
hint.setBorder(new ScaledEmptyBorder(4, 0, 0, 0));
|
||||
|
||||
JPanel buttons = new JPanel();
|
||||
JButton important = new JButton("Toggle important");
|
||||
@@ -187,12 +188,12 @@ final class NotificationsPanel extends JPanel {
|
||||
t.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
t.setShowGrid(false);
|
||||
t.setTableHeader(null);
|
||||
t.setRowHeight(Math.max(t.getRowHeight(), t.getFontMetrics(t.getFont()).getHeight() + 6));
|
||||
t.getColumnModel().getColumn(0).setMaxWidth(TOGGLE_COLUMN_WIDTH);
|
||||
t.getColumnModel().getColumn(0).setMinWidth(TOGGLE_COLUMN_WIDTH);
|
||||
t.setRowHeight(Math.max(t.getRowHeight(), t.getFontMetrics(t.getFont()).getHeight() + UIScale.scale(6)));
|
||||
t.getColumnModel().getColumn(0).setMaxWidth(UIScale.scale(TOGGLE_COLUMN_WIDTH));
|
||||
t.getColumnModel().getColumn(0).setMinWidth(UIScale.scale(TOGGLE_COLUMN_WIDTH));
|
||||
t.getColumnModel().getColumn(0).setCellRenderer(new ToggleRenderer(t.getDefaultRenderer(Boolean.class)));
|
||||
t.getColumnModel().getColumn(1).setCellRenderer(new ActionRenderer());
|
||||
t.setPreferredScrollableViewportSize(new Dimension(360, 260));
|
||||
t.setPreferredScrollableViewportSize(UIScale.scale(new Dimension(360, 260)));
|
||||
|
||||
t.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
@@ -381,11 +382,11 @@ final class NotificationsPanel extends JPanel {
|
||||
if (row.isHeading()) {
|
||||
setFont(base.deriveFont(Font.BOLD));
|
||||
setForeground(selected ? table.getSelectionForeground() : table.getForeground());
|
||||
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
|
||||
setBorder(new ScaledEmptyBorder(2, 2, 2, 2));
|
||||
setToolTipText(null);
|
||||
return this;
|
||||
}
|
||||
setBorder(BorderFactory.createEmptyBorder(2, 18, 2, 2));
|
||||
setBorder(new ScaledEmptyBorder(2, 18, 2, 2));
|
||||
setFont(base.deriveFont(working.isImportant(row.event) ? Font.BOLD : Font.PLAIN));
|
||||
boolean silent = !sounds.hasSound(row.event);
|
||||
setForeground(selected ? table.getSelectionForeground()
|
||||
|
||||
Reference in New Issue
Block a user