我是一名Windows用户,我开发了一个小程序来根据一些输入计算一些参数。 Windows 中的 GUI 按预期显示,但在 macOS 中却有所不同。请让我知道如何纠正它。相同的代码是。
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 输出(所需):
macOS 输出(需要修改):
按钮看起来不同的原因是 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)
方法。
这可以通过匿名类或仅让一个类扩展该对象并从那里覆盖它来实现:
JPanel myPanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//... draw stuffs
}
};
public class MyPanel extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// paint stuffs
}
}
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
我在main的开头插入了这段代码并解决了它