【发布时间】:2016-10-15 12:39:02
【问题描述】:
我尝试制作一个动态布局的 JFrame,看起来应该像这样
------------------------------------------|
| | Details |
| | |
| | |
| list | |
| | |
| | |
| | save |
-------------------------------------------
其中列表是一些树结构,当我选择某个元素时,该元素的详细信息会出现在详细信息中。现在详细信息由多个JPanels 组成,我将它们放入JPanel 和BoxLayout。在这个JPanel下方我有一个保存按钮。
由于有很多细节,我将JPanel 细节放入JScrollPane 但是,这个滚动窗格忽略了它的目的,结果是细节面板大于窗口大小。这是它一直到底部隐藏保存按钮,其余部分不可见。滚动条永远不会出现。
我不知道这是否与以下事实有关
这是我实例化所有内容的方式。首先在右侧面板中,我将所有JPanel 添加到firstPanel 中,然后在JPanel 底部放置一个按钮。那么
setLayout(new BorderLayout());
add(bottom, BorderLayout.SOUTH);
scrollPane=new JScrollPane(firstPanel);
JPanel conScroll = new JPanel(new GridLayout());
conScroll.add(scrollPane);
add(conScroll, BorderLayout.CENTER);
在JFrame 级别上,我实例化了左侧和右侧,但是我只放置了左侧,右侧的空JPanel 称为display。
当我选择一个元素时,我会更新firstPanel 中的所有元素,我会在右侧面板上调用revalidate() 和repaint()。然后在 Frame 级别删除 displayer 的所有元素,然后将右侧添加到 displayer。
按照建议,我做了一个最小的工作示例(更新)。
因此,对于这个最小的示例,我删除了左侧。剩下的是一个 JFrame EmpireEditor,里面有一个显示 JPanel,然后我在里面放了一个 unitEditor。 Uniteditor 包含两个JPanel,一个在中心,一个在南。中心的面板位于 JScrollPane 中。
package main;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
try {
// Set System L&F
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}
catch (UnsupportedLookAndFeelException e) {
// handle exception
}
catch (ClassNotFoundException e) {
// handle exception
}
catch (InstantiationException e) {
// handle exception
}
catch (IllegalAccessException e) {
// handle exception
}
@SuppressWarnings("unused")
EmpireEditor r = new EmpireEditor();
}
}
帝国编辑器
package main;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class EmpireEditor extends JFrame {
private JPanel display;
private UnitEditor unitEditor;
public EmpireEditor() {
super("Editor");
display = new JPanel();
unitEditor = new UnitEditor();
add(display);
display.add(unitEditor);
pack();
setVisible(true);
}
}
这里的 UnitEditor 是一个中心面板,我只是在其中填充了一个 PanelNumber,但这只是为了让里面有一些东西,我们可以看到滚动条没有出现。想法是底部始终存在,其余部分应填充JScrollPane。
package main;
import java.awt.BorderLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
@SuppressWarnings("serial")
public class UnitEditor extends JPanel {
private PanelNumbers numbers = new PanelNumbers();
private JScrollPane scrollPane;
public UnitEditor() {
super();
JPanel firstPanel = new JPanel();
firstPanel.setLayout(new BoxLayout(firstPanel, BoxLayout.Y_AXIS));
firstPanel.add(numbers);
JPanel bottom = new JPanel();
JButton save = new JButton("save");
bottom.add(save);
scrollPane=new JScrollPane(firstPanel);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(bottom,BorderLayout.SOUTH);
}
}
最后是PanelNumber,但可以用任何东西交换它。
package main;
import java.awt.GridLayout;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class PanelNumbers extends JPanel{
private Map<Value, JFormattedTextField> nums = new HashMap<>();
public PanelNumbers(){
super();
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
JFormattedTextField tmp;
JPanel numbers;
numbers = new JPanel();
numbers.setBorder(BorderFactory.createTitledBorder("Numbers"));
numbers.setLayout(new GridLayout(0, 6));
for (Value s : Value.values()) {
numbers.add(new JLabel(s.n()));
tmp = new JFormattedTextField(NumberFormat.getInstance());
setFocus(tmp);
numbers.add(tmp);
nums.put(s, tmp);
}
add(numbers);
}
public void setUnit(String name){
for (Value key : nums.keySet())
nums.get(key).setValue(0);
}
public void save(){
}
private int toNumber(String t) {
int res = 0;
try {
res = Integer.parseInt(t);
} catch (Exception e) {
}
return res;
}
private void setFocus(final JFormattedTextField num) {
num.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
num.selectAll();
}
});
}
});
//num.setPreferredSize(new Dimension(20, 10));
num.setMaximumSize(num.getPreferredSize());
}
public enum Value {
// Kampf
GROESSE("Groesse"),
WAFFENFERTIGKEIT("Waffenfertigkeit"),
FERNKAMPFFERTIGKEIT("Fernkampffertigkeit"),
ANGRIFFSBONUS("Angriffs Bonus"),
NAHKAMPFPANZERUNG("Panzerung nah"),
FERNKAMPFPANZERUNG("Panzerung fern"),
INITIATIVE("Initiative"),
TP("Treffer"),
// Mouvement
FELDER("Felder"),
BWS("Bewegungspunkte"),
B("B Befehl"),
A("A Befehl"),
P("P Befehl"),
H("H Befehl"),
M("Manoever"),
UEBERR("Ueberrenen"),
//Moral
FURCHTFAKTOR("Furchtfaktor"),
MORALERST("Erster Moralwert"),
MORALZWEIT("Zweiter Moralwert"),
//Rest
MAGIE("Magie"),
KONTROL("Kontrollbereich"),
STERNE("Sterne"),
ELEMENTE("Elemente"),
ELEMENTEPROFELD("Elemente pro Feld"),
KOSTEN("Kosten");
private String name;
Value(String name){
this.name = name;
}
public String n(){
return name;
}
}
}
【问题讨论】:
-
请强烈考虑创建和发布有效的minimal reproducible example。否则,我们将很难完全理解您的问题或帮助解决问题。
-
Now the Details consist of multiple JPanels- 您应该在详细信息面板上使用Box Layout,以便您可以根据选择轻松交换面板。 -
那些面板保持不变,我只一次动态添加右侧。晚了我会把这个换成另一个。我正在做一个最小的例子,但我需要安装 eclipse,因为我是在 AndroidStudio 上安装的,我正在疯狂地尝试再次制作一个 java 项目,不知道我第一次是如何做到的
-
感谢您的努力,但您的代码很少,因为它有太多与手头的问题完全无关的代码,而且我不知道它在做什么是对还是错。
-
将
display的布局设置为GridLayout(1,1)解决了这个问题,不知何故,原来的布局只是让内面板变得任意大,因此JScrollPane没有感觉到冲动使其自身更小并具有滚动条。
标签: java swing jscrollpane