JScrollPane Viewport 大于 Frame
JScrollPane Viewport bigger than Frame
我尝试制作一个具有动态布局的 JFrame,它应该如下所示
------------------------------------------|
| | Details |
| | |
| | |
| list | |
| | |
| | |
| | save |
-------------------------------------------
其中list是一些树状结构,当我选择某个元素时,该元素的详细信息出现在Details中。现在详细信息由多个 JPanels
组成,我将其放入 JPanel
和 BoxLayout
中。在这个 JPanel
下面我有一个保存按钮。
因为有很多细节,所以我把 JPanel
细节放到了 JScrollPane
中,但是这个 scrollPane 忽略了它的目的,结果是细节面板比 window 大小。这是它一直到隐藏保存按钮的底部,其余部分不可见。滚动条永远不会出现。
我不知道这是否与以下事实有关:当一个元素被 selected 时,我更新了 JScrollPane
中的 JPanel
或其他什么。
以下是我如何实例化所有内容。首先在右侧面板中,我在 firstPanel
中添加了所有 JPanel
,然后在 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
。
当我 select 一个元素时,我更新 firstPanel
内的所有元素,我在右侧面板上调用 revalidate()
和 repaint()
。然后在框架级别上,我删除了 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;
}
}
}
将 display
的布局设置为 GridLayout(1,1)
解决了问题,不知何故原始布局只是让内部面板变得尽可能大,因此 JScrollPane
没有有种想把它变小并有滚动条的冲动。
我尝试制作一个具有动态布局的 JFrame,它应该如下所示
------------------------------------------|
| | Details |
| | |
| | |
| list | |
| | |
| | |
| | save |
-------------------------------------------
其中list是一些树状结构,当我选择某个元素时,该元素的详细信息出现在Details中。现在详细信息由多个 JPanels
组成,我将其放入 JPanel
和 BoxLayout
中。在这个 JPanel
下面我有一个保存按钮。
因为有很多细节,所以我把 JPanel
细节放到了 JScrollPane
中,但是这个 scrollPane 忽略了它的目的,结果是细节面板比 window 大小。这是它一直到隐藏保存按钮的底部,其余部分不可见。滚动条永远不会出现。
我不知道这是否与以下事实有关:当一个元素被 selected 时,我更新了 JScrollPane
中的 JPanel
或其他什么。
以下是我如何实例化所有内容。首先在右侧面板中,我在 firstPanel
中添加了所有 JPanel
,然后在 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
。
当我 select 一个元素时,我更新 firstPanel
内的所有元素,我在右侧面板上调用 revalidate()
和 repaint()
。然后在框架级别上,我删除了 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;
}
}
}
将 display
的布局设置为 GridLayout(1,1)
解决了问题,不知何故原始布局只是让内部面板变得尽可能大,因此 JScrollPane
没有有种想把它变小并有滚动条的冲动。