Java 始终保持在x轴上相同位置的组件的建议布局?
我的情况有点复杂,所以我不想解释,我只想展示一下我目前拥有的东西: 我的想法是,我想把乐器选择器(每个棍子上都有“长笛”的组合框)移到棍子的上方。然而,我总是想把它放在同一个地方,在左边的工作人员正上方,即使是水平滚动。当垂直滚动时,它应该移动,以便始终位于其标尺的正上方。有点像工具栏。问题是它已经在一个JScrollPane中(因为可能有多个横杆,您需要滚动两个轴,每个员工都有一个“仪表板”(尽管最终会有其他UI元素在这个虚拟工具栏中与它连接的员工本地交互))。是否需要使用绝对定位+监听滚动/调整大小/窗口移动事件?或者有没有一个我不知道的布局可以做这种事情Java 始终保持在x轴上相同位置的组件的建议布局?,java,swing,jscrollpane,Java,Swing,Jscrollpane,我的情况有点复杂,所以我不想解释,我只想展示一下我目前拥有的东西: 我的想法是,我想把乐器选择器(每个棍子上都有“长笛”的组合框)移到棍子的上方。然而,我总是想把它放在同一个地方,在左边的工作人员正上方,即使是水平滚动。当垂直滚动时,它应该移动,以便始终位于其标尺的正上方。有点像工具栏。问题是它已经在一个JScrollPane中(因为可能有多个横杆,您需要滚动两个轴,每个员工都有一个“仪表板”(尽管最终会有其他UI元素在这个虚拟工具栏中与它连接的员工本地交互))。是否需要使用绝对定位+监听滚动
谢谢你的关注 我通过以下方法在一定程度上实现了这一点:
- 将一个布局为空的JPanel放在staff上
- 将组合框添加到此面板
- 使面板高度与组合框相同,宽度与标尺相同(可以滚动的宽度)
- 将
添加到水平条以更新组合框的坐标XAdjustmentListener
- 将组合框放在空布局面板中:
然后你把这个面板放在员工身上,不管你用什么布局。在我的例子中,我有一个垂直框布局的面板,包含comboBoxPanel和红色面板,工作人员将在其中JComboBox comboBox = new JComboBox(new String[]{"Flute", "Piano", "Cello"}); comboBox.setBounds(0, 0, comboBox.getPreferredSize().width, comboBox.getPreferredSize().height); _comboBoxes.add(comboBox); JPanel comboBoxPanel = new JPanel(); comboBoxPanel.setLayout(null); comboBoxPanel.add(comboBox);
- 将侦听器添加到滚动条并更新组合框在其面板中的位置:
scrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() { @Override public void adjustmentValueChanged(AdjustmentEvent e) { for (JComboBox comboBox : _comboBoxes) { comboBox.setLocation(e.getValue(), 0); } } });
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class ScrollIndependentTest
{
private ArrayList<JComboBox> _comboBoxes = new ArrayList<JComboBox>();
public static final void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
new ScrollIndependentTest().createAndShowGUI();
}
});
}
public void createAndShowGUI()
{
JFrame frame = new JFrame();
frame.setTitle("Fourier Synthesis");
JPanel listPanel = new JPanel();
listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
for (int i = 0; i < 10; ++i)
{
listPanel.add(createStaffPanel());
}
JScrollPane scrollPane = new JScrollPane(listPanel);
scrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener()
{
@Override
public void adjustmentValueChanged(AdjustmentEvent e)
{
for(JComboBox comboBox : _comboBoxes)
{
//if (comboBox.isVisible()) //maybe?
comboBox.setLocation(e.getValue(), 0);
}
}
});
frame.add(scrollPane);
/*
* Cosmetic elements to make it look more similar to your case
*/
JMenuBar menuBar = new JMenuBar();
menuBar.add(new JMenu("File"));
menuBar.add(new JMenu("Synthesis"));
menuBar.add(new JMenu("Help"));
frame.setJMenuBar(menuBar);
JPanel toolBar = new JPanel();
toolBar.setLayout(new BoxLayout(toolBar, BoxLayout.Y_AXIS));
for (int i = 0; i < 10; ++i)
{
toolBar.add(new JButton("Note " + i));
}
frame.add(toolBar, BorderLayout.WEST);
/*
* end
*/
frame.setSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel createStaffPanel()
{
JPanel staffPanel = new JPanel();
staffPanel.setLayout(new BoxLayout(staffPanel, BoxLayout.Y_AXIS));
staffPanel.setBorder(BorderFactory.createLineBorder(Color.black));
JComboBox comboBox = new JComboBox(new String[]{"Flute", "Piano", "Cello"});
comboBox.setBounds(0, 0, comboBox.getPreferredSize().width, comboBox.getPreferredSize().height);
_comboBoxes.add(comboBox);
JPanel comboBoxPanel = new JPanel();
comboBoxPanel.setLayout(null);
comboBoxPanel.add(comboBox);
comboBoxPanel.setPreferredSize(new Dimension(600, comboBox.getPreferredSize().height));
staffPanel.add(comboBoxPanel);
JPanel panel = new JPanel();
panel.setBackground(Color.red);
panel.setPreferredSize(new Dimension(600, 100));
panel.setAlignmentX(Component.LEFT_ALIGNMENT);
staffPanel.add(panel);
return staffPanel;
}
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Component;
导入java.awt.Dimension;
导入java.awt.event.AdjustmentEvent;
导入java.awt.event.AdjustmentListener;
导入java.util.ArrayList;
导入javax.swing.BorderFactory;
导入javax.swing.BoxLayout;
导入javax.swing.JButton;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JMenu;
导入javax.swing.JMenuBar;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.SwingUtilities;
公共类ScrollIndependentTest
{
私有ArrayList_ComboBox=新ArrayList();
公共静态最终void main(字符串[]args)
{
SwingUtilities.invokeLater(新的Runnable(){
公开募捐
{
新建ScrollIndependentTest().createAndShowGUI();
}
});
}
public void createAndShowGUI()
{
JFrame=新JFrame();
frame.setTitle(“傅里叶合成”);
JPanel listPanel=newjpanel();
setLayout(新的BoxLayout(listPanel,BoxLayout.Y_轴));
对于(int i=0;i<10;++i)
{
添加(createStaffPanel());
}
JScrollPane scrollPane=新的JScrollPane(列表面板);
scrollPane.getHorizontalScrollBar().addAdjustmentListener(新的AdjustmentListener())
{
@凌驾
公共无效调整值已更改(调整事件e)
{
for(JComboBox组合框:_组合框)
{
//if(comboBox.isVisible())//可能吗?
setLocation(例如getValue(),0);
}
}
});
frame.add(滚动窗格);
/*
*化妆元素,让它看起来更像你的情况
*/
JMenuBar menuBar=新的JMenuBar();
添加(新JMenu(“文件”);
菜单栏添加(新JMenu(“合成”));
添加(新JMenu(“帮助”);
frame.setJMenuBar(菜单栏);
JPanel toolBar=新的JPanel();
setLayout(新的BoxLayout(工具栏,BoxLayout.Y_轴));
对于(int i=0;i<10;++i)
{
添加(新的JButton(“Note”+i));
}
frame.add(工具栏,BorderLayout.WEST);
/*
*结束
*/
框架设置尺寸(新尺寸(500400));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
私有JPanel createStaffPanel()
{
JPanel staffPanel=新的JPanel();
staffPanel.setLayout(新的BoxLayout(staffPanel,BoxLayout.Y_轴));
staffPanel.setboorder(BorderFactory.createLineBorder(Color.black));
JComboBox组合框=新的JComboBox(新弦[]{“长笛”、“钢琴”、“大提琴”});
comboBox.setBounds(0,0,comboBox.getPreferredSize().width,comboBox.getPreferredSize().height);
_comboBox.add(comboBox);
JPanel comboxpanel=新的JPanel();
comboBoxPanel.setLayout(空);
comboBoxPanel.add(组合框);
comboBoxPanel.setPreferredSize(新维度(600,comboBox.getPreferredSize().height));
添加(comboBoxPanel);
JPanel面板=新的JPanel();
面板.立根背景(颜色.红色);
面板。设置首选尺寸(新尺寸(600100));
面板.setAlignmentX(组件左对齐);
staffPanel.add(面板);
返回工作人员面板;
}
}
我通过以下方法在一定程度上实现了这一点:
- 将一个布局为空的JPanel放在staff上
- 添加
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; public class ScrollSSCCE extends JPanel { public ScrollSSCCE() { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); BoundedRangeModel model = null; for (int i = 0; i < 5; i++) { JLabel label = new JLabel("Flute " + i); label.setAlignmentX(JComponent.LEFT_ALIGNMENT); add( label ); JTextArea textArea = new JTextArea(3, 20); textArea.setText("Just some text to make a horizontal scroll necessary"); JScrollPane scrollPane = new JScrollPane( textArea ); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setAlignmentX(JComponent.LEFT_ALIGNMENT); add( scrollPane ); // Share the horizontal scrollbar model JScrollBar horizontal = scrollPane.getHorizontalScrollBar(); if (i == 0) model = horizontal.getModel(); else horizontal.setModel( model ); } // Create the scrollbar that uses the shared model JScrollBar shared = new JScrollBar( JScrollBar.HORIZONTAL ); shared.setModel( model ); shared.setAlignmentX(JComponent.LEFT_ALIGNMENT); add( shared ); } private static void createAndShowUI() { JFrame frame = new JFrame("Scroll SSCCE"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add( new ScrollSSCCE() ); frame.setLocationByPlatform( true ); frame.setSize(200, 400); frame.setVisible( true ); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } }
if (i != 4) scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
JScrollPane master = new JScrollPane( new ScrollSSCCE() ); master.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); JFrame frame = new JFrame("Scroll SSCCE"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //frame.add( new ScrollSSCCE() ); frame.add( master ); frame.setLocationByPlatform( true ); frame.setSize(200, 400); frame.setVisible( true );