【发布时间】:2021-07-22 08:13:54
【问题描述】:
我正在尝试在 Java swing 中制作这种 UI,您可以在其中将内容从左侧菜单拖放到中间的一个单元格中,就像这张左右两侧可折叠的图像:
我目前的尝试让我处于这个奇怪的阶段: What actually happens
更奇怪的是,我已经放入左侧面板的内容只有在我将鼠标悬停在它上面时才会出现,并且在我使用拆分调整它的大小后它会再次消失。此外,只有一个我添加到面板的面板出现,而第二个面板无法出现: After moving divider Mouse moved over button now appears
在我的图表区域中,按钮拒绝移动到图表的顶部,除非我移动分隔线以使面板足够小以将其强制到顶部。相关代码在这里:
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import org.jfree.data.time.DynamicTimeSeriesCollection;
import org.jfree.data.time.Second;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYDataset;
/**
* @author CephDigital
*
*/
public class GUI extends JFrame{
DynamicTimeSeriesCollection dataset;
private Timer timer;
ActionListener timerAction = new ActionListener() {
float newData[] = new float[1];
@Override
public void actionPerformed(ActionEvent e) {
//Store new data to newData
dataset.advanceTime();
dataset.appendData(newData);
}
};
int size = 20;
DefaultComponent[][] graph = new DefaultComponent[size][size];
String saveDirectory = "";
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = (int)screenSize.getWidth(),
screenHeight = (int)screenSize.getHeight();
JButton btnGraphStart = new JButton("Place first point"),
btnGraphEnd = new JButton("Place end point"),
hidePower = new JButton("Power"),
hideResist = new JButton("Resistors"),
startSimulation = new JButton("Start"),
endSimulation = new JButton("End");
JMenuBar optionsBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem menuItem;
JPanel topMenuPanel = new JPanel(),
//compPanel = new JPanel(),
gridPanel = new JPanel(),
graphPanel = new JPanel(),
itemPanel,
globalPanel = new JPanel(),
resistorComps = new JPanel(),
resistorTotal = new JPanel(),
powerComps = new JPanel(),
powerTotal = new JPanel();
JScrollPane compPanel = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JToolBar simulationControl = new JToolBar("Simulation Control");
JSlider light;
JLabel lightTxt;
public GUI() {
//Setting up split panels
getContentPane().setLayout(new BorderLayout());
compPanel.setBackground(Color.BLUE);
gridPanel.setBackground(Color.CYAN);
gridPanel.setLayout(new GridLayout(size,size));
graphPanel.setBackground(Color.GREEN);
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, compPanel, gridPanel);
sp.setOneTouchExpandable(true);
sp.setMinimumSize(new Dimension(200, 400));
//sp.setDividerLocation(500);
JSplitPane sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, graphPanel);
sp2.setOneTouchExpandable(true);
//sp2.setDividerLocation(700);
//Setup the menu for the components panel
hideResist.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (resistorComps.isVisible()) {
resistorComps.setVisible(false);
} else {
resistorComps.setVisible(true);
}
}
});
hidePower.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (powerComps.isVisible()) {
powerComps.setVisible(false);
} else {
powerComps.setVisible(true);
}
}
});
//Panel for different power IO
powerComps.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
powerTotal.setLayout(new GridLayout(0, 1));
powerTotal.add(hidePower);
powerTotal.add(powerComps);
powerTotal.setSize(200, 200);
compPanel.add(powerTotal);
//Panel for different types of resistors
resistorComps.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
resistorTotal.setLayout(new GridLayout(0, 1));
resistorTotal.add(hideResist);
resistorTotal.add(resistorComps);
powerTotal.setSize(200, 200);
compPanel.add(resistorTotal);
//compPanel.setLayout(new GridLayout(1,2));
//compScroll.add(compPanel);
//Setup the grid panel
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
//Create a panel
itemPanel = new JPanel();
itemPanel.setPreferredSize(new Dimension(300, 300));
itemPanel.setSize(100, 100);
itemPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
gridPanel.add(itemPanel);
}
}
//Setup the graph panel
float[] voltageData = {};
dataset = new DynamicTimeSeriesCollection(1, 2 * 60, new Second());
dataset.setTimeBase(new Second(0, 0, 0, 1, 1, 2011));
dataset.addSeries(voltageData, 0, "Voltage");
JFreeChart chart = createChart(dataset);
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(btnGraphStart);
buttonPanel.add(btnGraphEnd);
graphPanel.setLayout(new BorderLayout());
graphPanel.add(buttonPanel, BorderLayout.PAGE_START);
graphPanel.add(new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}, BorderLayout.CENTER);
//Setup the global panel for global variables that the user can change
light = new JSlider(1, 100000, 1);
light.addChangeListener((ChangeEvent e) -> {
float text = (float)(light.getValue()) / 10;
lightTxt.setText(Float.toString(text));
});
lightTxt = new JLabel("0.1");
createLayout(globalPanel, new JLabel("Global Lux"), light, lightTxt);
//Set the location of components in the frame
this.setTitle("Circuit Simulator");
this.add(topMenuPanel, BorderLayout.NORTH);
this.add(sp2, BorderLayout.CENTER);
this.add(globalPanel, BorderLayout.SOUTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(1243, 679);
this.setVisible(true);
}
public static void main(String[] args) {
new GUI();
}
private JFreeChart createChart(XYDataset dataset) {
JFreeChart result = ChartFactory.createTimeSeriesChart(
"Title", "mm:ss", "Voltage", dataset, true, true, false);
XYPlot plot = result.getXYPlot();
ValueAxis domain = plot.getDomainAxis();
domain.setAutoRange(true);
ValueAxis range = plot.getRangeAxis();
range.setRange(0, 10);
return result;
}
private void createLayout(JComponent...arg) {
JPanel panel = (JPanel) arg[0];
GroupLayout gl = new GroupLayout(panel);
panel.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setAutoCreateGaps(true);
gl.setHorizontalGroup(gl.createParallelGroup()
.addComponent(arg[1])
.addComponent(arg[2])
.addComponent(arg[3])
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addComponent(arg[1])
.addComponent(arg[2])
.addComponent(arg[3])
);
pack();
}
}
我讨厌 GUI 制作,所以请有人帮我弄清楚这些废话。
【问题讨论】:
-
编辑您的问题并包含创建所有这些面板并设置其布局的代码。我们需要minimal reproducible example,以便我们自己查看您的问题。也就是说,您可能想阅读docs.oracle.com/javase/tutorial/uiswing/layout 以清楚地了解布局。
-
好的,代码已正确编辑。现在应该可以重现问题了。
-
这不是minimal reproducible example。您的问题是关于组件的布局。使用来自 JFreeChart 的组件与这个问题无关。您正在使用我无法访问的第 3 方课程。您可以只使用 JLabel 或其他东西来表示图表。无论如何,您的最后一个问题是为什么左侧的组件不显示。您似乎错过了关于一步一步解决问题的评论。您的 MRE 在哪里,它只是在拆分窗格中显示左侧面板?此外,所有 ActionListener 都与所述问题无关。监听器不会影响布局。
-
@CephDigital 菜单栏与所述问题无关。使用适当的 MRE,整个代码可能只有 30 行代码。几行来创建框架。一对夫妇创建拆分面板。还有一些可以为左侧组件创建嵌套面板。下面是一个使用拆分窗格处理问题的 MRE 示例。您应该可以对其进行修改以创建“左侧面板”,以尝试使其以您想要的方式显示:stackoverflow.com/a/45929359/131872。一旦你得到一个基本的例子,你就可以修复你的真实应用程序。
标签: java swing user-interface layout