Windows 和 Mac OS 中 GUI 的差异

问题描述 投票:0回答:2

我是一名Windows用户,我开发了一个小软件来根据一些输入计算一些参数。 Windows 中的 GUI 按预期显示,但在 Mac OS 中却有所不同。请让我知道如何纠正它。相同的代码是。

package home;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;

import java.awt.Component;
import java.awt.ComponentOrientation;

/**
 * Home Page for the application.
 * @author Harshit Rathore
 * 
 */
public class Home_Main {

    private JFrame f;
    private JXTabbedPane tabbedpane;
    private ImageIcon icon_view, icon_analysis, icon_algo, icon_info, icon_sche_gen;
    Schedule_Generation schedule_gen;
    View_JPanel2D view2d;
    View_JPanel3D view3d;
    MapJPanel mapPanel;

    Home_Main() {

        f = new JFrame();
        f.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        f.setTitle("Anti-Accidental Algorithm");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        tabbedpane = new JXTabbedPane(JTabbedPane.LEFT);
        AbstractTabRenderer renderer = (AbstractTabRenderer)tabbedpane.getTabRenderer();
        renderer.setPrototypeText("This text is a prototype->");
        renderer.setHorizontalTextAlignment(SwingConstants.LEADING);

        icon_view = new ImageIcon(this.getClass().getResource("/view_icon.png"));
        icon_analysis = new ImageIcon(this.getClass().getResource("/analysis_icon.png"));
        icon_algo = new ImageIcon(this.getClass().getResource("/algo_icon.png"));
        icon_info = new ImageIcon(this.getClass().getResource("/info_icon.png"));
        icon_sche_gen = new ImageIcon(this.getClass().getResource("/schedule_icon.png"));

        mapPanel = new home.MapJPanel();
        view2d = new home.View_JPanel2D();
        view3d = new home.View_JPanel3D();
        schedule_gen = new home.Schedule_Generation(view2d, view3d, mapPanel);

        tabbedpane.addTab("Algorithm", icon_algo, new home.Algo_JPanel());
        tabbedpane.addTab("<html>Schedule<br>Generation</html>", icon_sche_gen, schedule_gen);
        tabbedpane.addTab("<html>View Data 2D<br>(Azimuth, Elevation)</html>", icon_view, view2d);
        tabbedpane.addTab("<html>View Data 3D<br>(Azimuth, Elevation, Tilt)</html>", icon_view, view3d);
        tabbedpane.addTab("MapPanel", icon_info, mapPanel);
        tabbedpane.addTab("<html>Windload<br>Torque</html>", icon_analysis, new home.WindloadTorque());

        f.getContentPane().add(tabbedpane);
        f.setMinimumSize(new Dimension(1100, 800));
        f.setSize(1600, 800);
        f.setVisible(true);
        f.setEnabled(true);
    }
    
    /**
     * The main function of the software.
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Home_Main();
    }

    // custom tabbedpane

    class JXTabbedPane extends JTabbedPane {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private ITabRenderer tabRenderer = new DefaultTabRenderer();

        public JXTabbedPane() {
            super();
        }

        public JXTabbedPane(int tabPlacement) {
            super(tabPlacement);
        }

        public JXTabbedPane(int tabPlacement, int tabLayoutPolicy) {
            super(tabPlacement, tabLayoutPolicy);
        }

        public ITabRenderer getTabRenderer() {
            return tabRenderer;
        }

        public void setTabRenderer(ITabRenderer tabRenderer) {
            this.tabRenderer = tabRenderer;
        }

        @Override
        public void addTab(String title, Component component) {
            this.addTab(title, null, component, null);
        }

        @Override
        public void addTab(String title, Icon icon, Component component) {
            this.addTab(title, icon, component, null);
        }

        @Override
        public void addTab(String title, Icon icon, Component component, String tip) {
            super.addTab(title, icon, component, tip);
            int tabIndex = getTabCount() - 1;
            Component tab = tabRenderer.getTabRendererComponent(this, title, icon, tabIndex);
            super.setTabComponentAt(tabIndex, tab);
        }
    }

    interface ITabRenderer {

        public Component getTabRendererComponent(JTabbedPane tabbedPane, String text, Icon icon, int tabIndex);

    }

    abstract class AbstractTabRenderer implements ITabRenderer {

        private String prototypeText = "";
        private Icon prototypeIcon = new ImageIcon(this.getClass().getResource("/view_icon.png"));
        private int horizontalTextAlignment = SwingConstants.CENTER;
        private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

        public AbstractTabRenderer() {
            super();
        }

        public void setPrototypeText(String text) {
            String oldText = this.prototypeText;
            this.prototypeText = text;
            firePropertyChange("prototypeText", oldText, text);
        }

        public String getPrototypeText() {
            return prototypeText;
        }

        public Icon getPrototypeIcon() {
            return prototypeIcon;
        }

        public void setPrototypeIcon(Icon icon) {
            Icon oldIcon = this.prototypeIcon;
            this.prototypeIcon = icon;
            firePropertyChange("prototypeIcon", oldIcon, icon);
        }

        public int getHorizontalTextAlignment() {
            return horizontalTextAlignment;
        }

        public void setHorizontalTextAlignment(int horizontalTextAlignment) {
            this.horizontalTextAlignment = horizontalTextAlignment;
        }

        public PropertyChangeListener[] getPropertyChangeListeners() {
            return propertyChangeSupport.getPropertyChangeListeners();
        }

        public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
            return propertyChangeSupport.getPropertyChangeListeners(propertyName);
        }

        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }

        public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
        }

        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
            PropertyChangeListener[] listeners = getPropertyChangeListeners();
            for (int i = listeners.length - 1; i >= 0; i--) {
                listeners[i].propertyChange(new PropertyChangeEvent(this, propertyName, oldValue, newValue));
            }
        }
    }

    class DefaultTabRenderer extends AbstractTabRenderer implements PropertyChangeListener {

        private Component prototypeComponent;

        public DefaultTabRenderer() {
            super();
            prototypeComponent = generateRendererComponent(getPrototypeText(), getPrototypeIcon(),
                    getHorizontalTextAlignment());
            addPropertyChangeListener(this);
        }

        private Component generateRendererComponent(String text, Icon icon, int horizontalTabTextAlignmen) {
            JPanel rendererComponent = new JPanel(new GridBagLayout());
            rendererComponent.setOpaque(false);

            GridBagConstraints c = new GridBagConstraints();
            c.insets = new Insets(2, 4, 2, 4);
            c.fill = GridBagConstraints.HORIZONTAL;
            rendererComponent.add(new JLabel(icon), c);

            c.gridx = 1;
            c.weightx = 1;
            rendererComponent.add(new JLabel(text, horizontalTabTextAlignmen), c);

            return rendererComponent;
        }

        @Override
        public Component getTabRendererComponent(JTabbedPane tabbedPane, String text, Icon icon, int tabIndex) {
            Component rendererComponent = generateRendererComponent(text, icon, getHorizontalTextAlignment());
            int prototypeWidth = prototypeComponent.getPreferredSize().width;
            int prototypeHeight = prototypeComponent.getPreferredSize().height;
            rendererComponent.setPreferredSize(new Dimension(prototypeWidth, prototypeHeight));
            return rendererComponent;
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            String propertyName = evt.getPropertyName();
            if ("prototypeText".equals(propertyName) || "prototypeIcon".equals(propertyName)) {
                this.prototypeComponent = generateRendererComponent(getPrototypeText(), getPrototypeIcon(),
                        getHorizontalTextAlignment());
            }
        }
    }
}

输出是-

第一个来自Windows(需要一个)第二个来自Mac OS(需要修改)。 Windows Output (Desired) Mac OS Output(Need Modification)

谢谢你

java windows macos swing user-interface
2个回答
1
投票

按钮看起来不同的原因是 Java Swing 的 LAF (Look & Feel)。

外观就像 Swing 应用程序的主“主题”,它定义了某些组件的外观等具体规则……

Windows 上的 Java Swing 看起来与 Unix 和 OSX 上不同,因为 LAF 有不同的提供者(称为 LAF“金属”)

因此,您可以将 LAF 库打包到您的程序中,您可以在here找到许多库。 要调用要使用的主题,您必须将其放置在调用任何 GUI/Swing 事件(也称为重绘、组件初始化等)之前:

try {
   UIManager.setLookAndFeel(myThemeLAF.class.getName());
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
   e.printStackTrace();
}

或者,您可以重写各个

paintComponent(Graphics g)
方法。

这可以通过匿名类来实现,或者只是让一个类扩展该对象并从那里覆盖它:

  • #1 匿名内部类
JPanel myPanel = new JPanel() {
   @Override
   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      //... draw stuffs
   }
};
  • #2 扩展现有对象
public class MyPanel extends JPanel {
   @Override
   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      // paint stuffs
   }
} 

0
投票
try {
            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
© www.soinside.com 2019 - 2024. All rights reserved.