Пользовательская кнопка, не работающая с mac (ButtonUI)

У меня есть приложение, которое использует пользовательские кнопки повсюду для текста и значков. Отлично подходит для Windows и Linux, но теперь пользователи OSX жалуются. Текст не отображается на mac, просто «…». Код кажется достаточно простым, но я не знаю, когда дело доходит до macs. Как я могу это исправить?

Прецедент:

package example.swingx; import example.utils.ResourceLoader; import com.xduke.xlayouts.XTableLayout; import javax.swing.*; import javax.swing.plaf.ComponentUI; import java.awt.*; import java.awt.event.ActionEvent; public class SmallButton extends JButton { private static ComponentUI ui = new SmallButtonUI(); public SmallButton() { super(); /* final RepaintManager repaintManager = RepaintManager.currentManager(this); repaintManager.setDoubleBufferingEnabled(false); setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION);*/ } public SmallButton(AbstractAction action) { super(action); } public SmallButton(String text) { super(text); } public SmallButton(Icon icon) { super(icon); } public void updateUI() { setUI(ui); } public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JPanel buttonPanel = new JPanel(new XTableLayout()); SmallButton firstSmallButton = new SmallButton("One"); SmallButton secondSmallButton = new SmallButton("Two"); SmallButton thirdSmallButton = new SmallButton(); ImageIcon cameraIcon = (ImageIcon) ResourceLoader.getIcon("camera"); SmallButton fourth = new SmallButton(); fourth.setAction(new AbstractAction() { public void actionPerformed(ActionEvent e) { System.out.println("Fourth button pressed!"); } }); fourth.setIcon(cameraIcon); buttonPanel.add(firstSmallButton, "+"); buttonPanel.add(secondSmallButton, "+"); buttonPanel.add(thirdSmallButton, "+"); buttonPanel.add(fourth, "+"); final Container container = frame.getContentPane(); container.add(buttonPanel); frame.pack(); frame.setVisible(true); } } 

UI:

 package example.swingx; import javax.swing.*; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicButtonUI; import java.awt.*; public class SmallButtonUI extends BasicButtonUI { private static final Color FOCUS_COLOR = new Color(0, 0, 0); private static final Color BACKGROUND_COLOR = new Color(173, 193, 226); private static final Color SELECT_COLOR = new Color(102, 132, 186); private static final Color DISABLE_TEXT_COLOR = new Color(44, 44, 61); private static final Insets DEFAULT_SMALLBUTTON_MARGIN = new Insets(2, 4, 2, 4); private final static SmallButtonUI smallButtonUI = new SmallButtonUI(); public static ComponentUI createUI(JComponent component) { return smallButtonUI; } protected Color getSelectColor() { return SELECT_COLOR; } protected Color getDisabledTextColor() { return DISABLE_TEXT_COLOR; } protected Color getFocusColor() { return FOCUS_COLOR; } public void paint(Graphics g, JComponent c) { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); super.paint(g, c); } protected void paintButtonPressed(Graphics graphics, AbstractButton button) { if (button.isContentAreaFilled()) { Dimension size = button.getSize(); graphics.setColor(getSelectColor()); graphics.fillRect(0, 0, size.width, size.height); } } public Dimension getMinimumSize(JComponent component) { final AbstractButton button = ((AbstractButton) component); // Handle icon buttons: Icon buttonIcon = button.getIcon(); if (buttonIcon != null) { return new Dimension( buttonIcon.getIconWidth(), buttonIcon.getIconHeight() ); } // Handle text buttons: final Font fontButton = button.getFont(); final FontMetrics fontMetrics = button.getFontMetrics(fontButton); final String buttonText = button.getText(); if (buttonText != null) { final int buttonTextWidth = fontMetrics.stringWidth(buttonText); return new Dimension(buttonTextWidth + 15, fontMetrics.getHeight() + 5); } return null; } protected void installDefaults(AbstractButton button) { super.installDefaults(button); button.setMargin(DEFAULT_SMALLBUTTON_MARGIN); button.setBackground(getBackgroundColor()); } private Color getBackgroundColor() { return BACKGROUND_COLOR; } public Dimension getPreferredSize(JComponent component) { return getMinimumSize(component); } public Dimension getMaximumSize(JComponent component) { return super.getMinimumSize(component); } public SmallButtonUI() { super(); } } 

EDIT: после отладки кажется, что getMinimumSize () одинаково на обеих платформах. Кроме того, когда я останавливаюсь в любом месте Графика используется, кажется, что mac имеет значение transY 47, а linux – 0. Этот 47, похоже, также попадает в области отсечения. Где это может быть установлено? \

Ваш расчет предпочтительного размера неверен.

BasicButtonUI использует SwingUtilities.layoutCompoundLabel , рассмотренный здесь . В метке добавляется многоточие, если строка слишком длинная, но кнопка обычно имеет размер, соответствующий всему тексту.

Отсутствие лучшего понимания вашего контекста, я бы использовал параметр sizeVariant , показанный ниже. Я также показал простой пример BasicButtonUI используя меньший производный Font . Меню UI можно использовать совместно с Quaqua для тестирования.

образ

 import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import javax.swing.AbstractButton; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.plaf.basic.BasicButtonUI; /** * @see https://stackoverflow.com/a/14599176/230513 * @see https://stackoverflow.com/a/11949899/230513 */ public class Test { private void display() { JFrame f = new JFrame("Test"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setBackground(new Color(0xfff0f0f0)); f.setLayout(new GridLayout(0, 1)); f.add(createToolBar(f)); f.add(variantPanel("mini")); f.add(variantPanel("small")); f.add(variantPanel("regular")); f.add(variantPanel("large")); JPanel customPanel = new JPanel(); customPanel.add(createCustom("One")); customPanel.add(createCustom("Two")); customPanel.add(createCustom("Three")); f.add(customPanel); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private static JPanel variantPanel(String size) { JPanel variantPanel = new JPanel(); variantPanel.add(createVariant("One", size)); variantPanel.add(createVariant("Two", size)); variantPanel.add(createVariant("Three", size)); return variantPanel; } private static JButton createVariant(String name, String size) { JButton b = new JButton(name); b.putClientProperty("JComponent.sizeVariant", size); return b; } private static JButton createCustom(String name) { JButton b = new JButton(name) { @Override public void updateUI() { super.updateUI(); setUI(new CustomButtonUI()); } }; return b; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new Test().display(); } }); } private static class CustomButtonUI extends BasicButtonUI { private static final Color BACKGROUND_COLOR = new Color(173, 193, 226); private static final Color SELECT_COLOR = new Color(102, 132, 186); @Override protected void paintText(Graphics g, AbstractButton b, Rectangle r, String t) { super.paintText(g, b, r, t); g.setColor(SELECT_COLOR); g.drawRect(rx, ry, r.width, r.height); } @Override protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) { super.paintFocus(g, b, viewRect, textRect, iconRect); g.setColor(Color.blue.darker()); g.drawRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height); } @Override protected void paintButtonPressed(Graphics g, AbstractButton b) { if (b.isContentAreaFilled()) { g.setColor(SELECT_COLOR); g.fillRect(0, 0, b.getWidth(), b.getHeight()); } } @Override protected void installDefaults(AbstractButton b) { super.installDefaults(b); b.setFont(b.getFont().deriveFont(11f)); b.setBackground(BACKGROUND_COLOR); } public CustomButtonUI() { super(); } } private static JToolBar createToolBar(final Component parent) { final UIManager.LookAndFeelInfo[] available = UIManager.getInstalledLookAndFeels(); List names = new ArrayList(); for (UIManager.LookAndFeelInfo info : available) { names.add(info.getName()); } final JComboBox combo = new JComboBox(names.toArray()); String current = UIManager.getLookAndFeel().getName(); combo.setSelectedItem(current); combo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { int index = combo.getSelectedIndex(); try { UIManager.setLookAndFeel( available[index].getClassName()); SwingUtilities.updateComponentTreeUI(parent); } catch (Exception e) { e.printStackTrace(System.err); } } }); JToolBar bar = new JToolBar("L&F"); bar.setLayout(new FlowLayout(FlowLayout.LEFT)); bar.add(combo); return bar; } } 
  • Java - Как перетащить JPanel с его компонентами
  • Обновляйте JLabel несколько раз с результатами многолетней задачи
  • Безопасно ли создавать виджеты Swing / AWT NOT на тему Dispatch Event?
  • Java JFrame .setSize (x, y) не работает?
  • Как рассчитать количество строк (и столбцов в каждой строке), которые текст принимает в JTextArea?
  • SwingWorker, done () выполняется до завершения вызовов ()
  • JTable + Сортировка определенного поля
  • setOpaque (истина / ложь); Ява
  • JFrame.setBackground () не работает - почему?
  • JOptionPane - проверка ввода пользователем и предотrotation закрытия до тех пор, пока не будут выполнены условия
  • проблема отображения курсора java wait
  • Давайте будем гением компьютера.