我有一个JFrame
,其中包含2个JPanels
,其中一个是JFrame
的70%,另一个是剩下的30%。宽度为30%的JPanel
内嵌有一个嵌套的JPanel。但是,这个嵌套的JPanel
应该是其父JPanel宽度的50%,但是当它显示时,它占用了父JPanel
的全宽。
父JPanel
属于width 358
和height 772
,嵌套JPanel
具有以下值:width 179
和height 772
我已将这些组件的颜色设置为绿色和灰色,因此我可以很容易地看到它们是否正确渲染。当我运行我的应用程序时,嵌套的JPanel
实际上被渲染,好像它是parent
的整个宽度(整个区域呈现为绿色)。
这是当前的代码。
public class DisplayFrame extends JFrame{
private final static int WIDTH = 1200;
private final static int HEIGHT = 800;
private DisplayCanvas canvas;
private ControlContainer controlContainer;
public DisplayFrame() {
//simple inheritance.
super(title);
setSize(new Dimension(WIDTH, HEIGHT));
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addComponents(this.getContentPane());
}
public void addComponents(Container container){
canvas = DisplayCanvas.getInstance(container);
canvas.setAlignmentX(Component.LEFT_ALIGNMENT);
container.add(canvas);
controlContainer = ControlContainer.getInstance(container);
controlContainer.setAlignmentX(Component.RIGHT_ALIGNMENT);
container.add(controlContainer);
}
}
宽度为70%的面板
public class DisplayCanvas extends JPanel{
private final double WIDTH_PERCENT = 70;
private static DisplayCanvas instance;
private DisplayCanvas(Container parent) {
this.setSize(new Dimension(MathHelper.calculateXPercentOfY(WIDTH_PERCENT,
parent.getWidth()), parent.getHeight()));
this.setBackground(Color.WHITE);
this.setVisible(true);
}
//implement the singleton
public static DisplayCanvas getInstance(Container parent) {
if(instance != null){
return instance;
}
instance = new DisplayCanvas(parent);
return instance;
}
}
宽度为30%的面板:
public class ControlContainer extends JPanel{
private final double WIDTH_PERCENT = 30;
private static ControlContainer instance;
private ControlPanel controlPanel;
private ControlContainer(Container parent) {
this.setSize(new Dimension(MathHelper.calculateXPercentOfY(WIDTH_PERCENT,
parent.getWidth()), parent.getHeight()));
this.setBackground(Color.GRAY);
this.setLayout(new BorderLayout(0,0));
this.setVisible(true);
addControlElements(this);
}
//implement Singelton
public static ControlContainer getInstance(Container parent){
if(instance != null){
return instance;
}
instance = new ControlContainer(parent);
return instance;
}
public void addControlElements(Container parent){
controlPanel = ControlPanel.getInstance(parent);
controlPanel.setAlignmentX(LEFT_ALIGNMENT);
System.out.println("ControlContainer: " + parent.getWidth()
+ " " + parent.getHeight()+ " vis: " + parent.isVisible());
System.out.println("ControlPanel: " + controlPanel.getWidth()
+ " " + controlPanel.getHeight() + " vis: " + controlPanel.isVisible());
parent.add(controlPanel, BorderLayout.CENTER);
}
}
现在,此面板应嵌套在ControlContainer
内,宽度的50%。
public class ControlPanel extends JPanel{
private final double WIDTH_PERCENT = 50;
private static ControlPanel instance;
private ControlPanel(Container parent) {
super.setSize(new Dimension(MathHelper.calculateXPercentOfY(WIDTH_PERCENT,
parent.getWidth()), parent.getHeight()));
super.setBackground(Color.GREEN);
super.setVisible(true);
}
//implement singelton measures
public static ControlPanel getInstance(Container parent){
if(instance != null){
return instance;
}
instance = new ControlPanel(parent);
return instance;
}
}
这是addControlElements
方法的输出:
ControlContainer: 358 772 vis: true
ControlPanel: 179 772 vis: true
这仅用于测试值是否按预期设置,因为您可以看到ControlPanel
width is 179
这是预期的,但是在渲染时它会填充整个{{1} }。
希望你理解我的意思,这不是最容易解释的。
答案 0 :(得分:1)
首先看看Laying Out Components Within a Container,了解如何在Swing中使用组件。看看How to Use GridBagLayout,了解如何实现您正在寻找的结果
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.text.NumberFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new BasePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BasePane extends JPanel {
public BasePane() {
TestPane top = new TestPane();
TestPane bottom = new TestPane();
// top.setBorder(new LineBorder(Color.RED));
// bottom.setBorder(new LineBorder(Color.BLUE));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 0.3;
add(top, gbc);
gbc.gridy++;
gbc.weighty = 0.7;
add(bottom, gbc);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class TestPane extends JPanel {
public TestPane() {
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Dimension mySize = getSize();
Dimension parentSize = getParent().getSize();
String widthPer = NumberFormat.getPercentInstance().format((float) mySize.width / (float) parentSize.width);
String heightPer = NumberFormat.getPercentInstance().format((float) mySize.height / (float) parentSize.height);
String[] text = new String[]{
"Me = " + mySize.width + "x" + mySize.height,
"Parent = " + parentSize.height + "x" + parentSize.height,
"Perctange = " + widthPer + "x" + heightPer
};
FontMetrics fm = g2d.getFontMetrics();
int y = (getHeight() - (fm.getHeight() * text.length)) / 2;
for (String value : text) {
int x = (getWidth() - fm.stringWidth(value)) / 2;
g2d.drawString(value, x, y + fm.getAscent());
y += fm.getHeight();
}
g2d.dispose();
}
}
}