如何在Quaqua中获得统一的工具栏?

时间:2013-12-18 05:15:17

标签: java macos swing toolbar quaqua

我无法弄清楚如何强迫Quaqua在我的窗口上使用统一的工具栏。

我已经做了我所看到的其他帖子建议修复的所有内容。大多数人似乎忘记了setFloatable(false),但我们总是那样。

无论如何,我把它浓缩成一个简单的例子:

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import ch.randelshofer.quaqua.QuaquaManager;

public class QuaquaUnifiedToolbarTest implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new QuaquaUnifiedToolbarTest());
    }

    @Override
    public void run() {
        try {
            UIManager.setLookAndFeel(QuaquaManager.getLookAndFeel());
        } catch (UnsupportedLookAndFeelException e) {
            // Ignore it.
        }

        JToolBar toolBar = new JToolBar();
        toolBar.putClientProperty("Quaqua.ToolBar.style", "title");
        toolBar.setFloatable(false);

        ButtonGroup paneButtonGroup = new ButtonGroup();
        for (int i = 1; i <= 3; i++) {
            JToggleButton button = new JToggleButton("Section " + i);
            button.setIcon(new PlaceholderIcon());
            button.setHorizontalTextPosition(SwingConstants.CENTER);
            button.setVerticalTextPosition(SwingConstants.BOTTOM);
            button.putClientProperty("JComponent.sizeVariant", "small");
            button.putClientProperty("Quaqua.Button.style", "toolBarTab");
            paneButtonGroup.add(button);
            toolBar.add(button);
        }

        JDialog dialog = new JDialog(null, "Preferences", Dialog.ModalityType.MODELESS);
        dialog.setLayout(new BorderLayout());
        dialog.add(toolBar, BorderLayout.PAGE_START);
        dialog.setSize(800, 600);
        dialog.setVisible(true);
    }

    private static class PlaceholderIcon implements Icon {
        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_SQUARE,
                                          BasicStroke.JOIN_BEVEL, 1.0f,
                                          new float[] {  2.0f, 2.0f }, 1.0f));
            g2d.draw(new Rectangle(x, y, 32, 32));
        }

        @Override
        public int getIconWidth() {
            return 32;
        }

        @Override
        public int getIconHeight() {
            return 32;
        }
    }
}

结果如下:

screenshot of my example

这就是Transmission的样子:

screenshot of Transmission

我们的示例工具栏缺少统一的工具栏着色。此外,您无法使用鼠标拖动工具栏来拖动窗口。我确信这两个问题都来自同一个问题,Quaqua不知何故没有意识到我希望这个工具栏统一。

我已尝试在根窗格中将apple.awt.brushMetalLook设置为true。这会产生负面影响,使窗口始终处于禁用状态,并且无法帮助它显示为统一工具栏。

(( 其他与此问题无关的其他视觉问题:

  1. 对文本的抗锯齿不使用LCD式抗锯齿(这是Java 7中的一个没有已知解决方法的错误。)
  2. 没有浮雕(我想我知道如何解决这个问题,但它会涉及制作我自己的ButtonUI。)
  3. 活动按钮只是阴影较暗,而在真实按钮中,有一些“推入”外观(奇怪的是,默认的AquaToggleButtonUI得到了这个权利,所以这是一个罕见的情况,Quaqua提供了较少的原生看起来比默认。) ))

1 个答案:

答案 0 :(得分:0)

这是一个非常hacky的解决方案,它依赖于禁用Quaqua的位来让root窗格做正确的事情,因为我发现默认的Aqua外观确实可以正常工作。

奇怪的事情:

  • Quaqua删除工具栏按钮上的边框。
  • 如果您尝试使用JDialog而不是JFrame,则会遇到原始问题。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.HashSet;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

import ch.randelshofer.quaqua.QuaquaManager;

public class SheetTest implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SheetTest());
    }

    @Override
    public void run() {
        try {
            QuaquaManager.setExcludedUIs(new HashSet<>(Arrays.<String>asList(
                "RootPane"
            )));
            UIManager.setLookAndFeel(QuaquaManager.getLookAndFeel());
        } catch (Exception ignored) {}

        JButton button = new JButton("Sheet me!");
        JToolBar toolBar = new JToolBar();
        JScrollPane content = new JScrollPane();
        JFrame frame = new JFrame();

        toolBar.setFloatable(false);
        toolBar.setOpaque(false);
        toolBar.add(button);

        frame.setLayout(new BorderLayout());
        frame.add(toolBar, BorderLayout.PAGE_START);
        frame.add(content, BorderLayout.CENTER);
        // Under current Aqua L&F, this doesn't actually look like brushed metal.
        // It looks like normal window titles.
        frame.getRootPane().putClientProperty("apple.awt.brushMetalLook", true);
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}