Java Swing JScrollPane-如何将垂直滚动条设置为左侧?
请看标题。我曾尝试将组件方向更改为Java Swing JScrollPane-如何将垂直滚动条设置为左侧?,java,swing,jscrollpane,Java,Swing,Jscrollpane,请看标题。我曾尝试将组件方向更改为从右到左,但这产生了意外的副作用-对于具有指定首选大小的组件,其行为异常 (JDK1.6.0_23,EclipseVE) 编辑 以下是这方面的例子: 我们有JFrame,上面有jMainScrollPane。在jMainScrollPane中,我们放置了一个jMainPanel。现在将jMainPanel的首选大小设置为比jMainScrollPane窄jMainPanel仍将占用jMainScrollPane上的所有空间。现在将jMainScrollPane的
从右到左
,但这产生了意外的副作用-对于具有指定首选大小的组件,其行为异常
(JDK1.6.0_23,EclipseVE)
编辑
以下是这方面的例子:
我们有JFrame
,上面有jMainScrollPane
。在jMainScrollPane
中,我们放置了一个jMainPanel
。现在将jMainPanel
的首选大小设置为比jMainScrollPane
窄jMainPanel
仍将占用jMainScrollPane
上的所有空间。现在将jMainScrollPane
的方向更改为从右到左
,看看会发生什么
示例代码(更改jMainScrollPane的方向以查看差异):
EDIT2
由于这种奇怪的性质,我向Oracle提交了一个bug。他们给我寄了个bug链接
目前还没有这样的错误-我想,它正在被检查
但问题仍然存在——是否有解决办法或其他方法?同意OP:这是bug。RToL方向的设置触发viewPosition的计算。这发生在布局完成之前。在这种情况下,JViewport返回视图的preferredSize,而不是其实际大小(此时为零)。在肠道深处,BasicScrollPaneUI.Handler不知道这个伪造的尺寸,而是根据不正确的数据进行计算 这里有一些代码可供使用(OPs原版被进一步剥离,添加了彩色边框以查看内容的位置): 初始布局完全错误(如OP所报告),用按钮切换CO两次-布局看起来不错
一个快速而肮脏的攻击可能就是在生产上下文中这样做:在初始布局之后,强制CO进入LToR以允许正确的坐标,然后返回RToL @Manoj的副本似乎@freezed_Spider已经尝试了上述问题的答案,但对结果并不满意。@freezed_Spider在你写“内部布局被破坏”时,你能告诉我们你的意思吗?还是发送截图?我同意。给定的解决方案应该有效。我已经用
JScrollpane
在JTable
上测试了它。JScrollpane
没有任何首选大小设置。我注意到您有两个JScrollpane
s…主视图查看jMainPanel
,第二个视图什么也看不到。你为什么要这样设计?如果您想触发jMainPanel
的垂直滚动条,则只需jMainPanel.setPreferredSize(新维度(500400))代码>并删除对第二个JScrollPane
的需要,我看不出它有什么用途。谢谢你,肮脏的黑客工作:)我也发布了一个bug链接,但是-不好意思-我描述了一个比你描述的bug严重得多的bug。@冻结蜘蛛很高兴它能为你工作:-)评论id是什么(自动bug响应上的编号)?这个bug到底有什么秘密出于安全原因,有些Bug没有包含在Bug数据库中。
无论如何,在Bug ID发布到问题底部之前,已经报告过了:7038455
@eee:看来,你是对的。我很高兴他们知道这件事。
import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class TestFrame extends JFrame {
private JPanel jContentPane = null;
private JScrollPane jMainScrollPane = null;
private JPanel jMainPanel = null;
public TestFrame(){
super();
initialize();
}
private void initialize(){
this.setSize(480, 339);
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}
private JPanel getJContentPane(){
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getJMainScrollPane(), BorderLayout.CENTER);
}
return jContentPane;
}
private JScrollPane getJMainScrollPane(){
if (jMainScrollPane == null) {
jMainScrollPane = new JScrollPane();
jMainScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jMainScrollPane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
jMainScrollPane.setViewportView(getJMainPanel());
}
return jMainScrollPane;
}
private JPanel getJMainPanel(){
if (jMainPanel == null) {
jMainPanel = new JPanel();
jMainPanel.setLayout(new BorderLayout());
jMainPanel.setPreferredSize(new Dimension(30, 30));
}
return jMainPanel;
}
}
public class COInScrollPane extends JFrame {
public COInScrollPane(){
super();
initialize();
}
private void initialize(){
this.setTitle("JFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JScrollPane jMainScrollPane = getJMainScrollPane();
this.add(jMainScrollPane);
this.setSize(480, 339);
Action action = new AbstractAction("Toggle CO") {
@Override
public void actionPerformed(ActionEvent e) {
ComponentOrientation co = jMainScrollPane.getComponentOrientation().isLeftToRight() ?
ComponentOrientation.RIGHT_TO_LEFT : ComponentOrientation.LEFT_TO_RIGHT;
jMainScrollPane.applyComponentOrientation(co);
jMainScrollPane.revalidate();
jMainScrollPane.repaint();
}
};
add(new JButton(action), BorderLayout.SOUTH);
}
private JScrollPane getJMainScrollPane() {
JScrollPane jMainScrollPane = new JScrollPane(getJMainPanel());
jMainScrollPane.setViewportBorder(BorderFactory
.createLineBorder(Color.GREEN));
jMainScrollPane
.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
return jMainScrollPane;
}
private JPanel getJMainPanel() {
JPanel jMainPanel = new JPanel();
jMainPanel.add(new JButton("just a button"));
jMainPanel.setBorder(BorderFactory.createLineBorder(Color.RED));
return jMainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new COInScrollPane().setVisible(true);
}
});
}
}