Java 从右到左方向按钮大小的不相关变化
我将9个JButton添加到jpanel,将面板添加到jscrollpane,并将其添加到jframeJava 从右到左方向按钮大小的不相关变化,java,swing,orientation,jscrollpane,right-to-left,Java,Swing,Orientation,Jscrollpane,Right To Left,我将9个JButton添加到jpanel,将面板添加到jscrollpane,并将其添加到jframe scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 通过以下方式更改帧方向时: applycomponentation(组件方向:从右到左) scpBut
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
通过以下方式更改帧方向时:
applycomponentation(组件方向:从右到左)代码>
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
面板向右移动,按钮的大小固定,无法填充面板,但在下图中可以看到,scrolbar填充了面板的所有宽度
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
(我使用gridbaglayout添加按钮,使用borderlayout.center添加滚动窗格)
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
这是java中的一个bug还是
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
编辑:
这是最简单的观点。有帮助吗
import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class MyFrame extends JFrame{
private JButton[] arrayButton = new JButton[9];
private JButton btnLeft = new JButton("<");
private JButton btnRight = new JButton(">");
private JScrollPane scpButtons = new JScrollPane();
public MyFrame() {
for (int i = 0; i < arrayButton.length; i++)
arrayButton[i] = new JButton("btn");
JPanel pnlButton = initPnlButton();
scpButtons.setViewportView(pnlButton);
setLayout(new BorderLayout());
add(scpButtons, BorderLayout.CENTER);
// comment it and see the result
applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
}
private JPanel initPnlButton() {
JPanel pnlButton = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, 10,
1, new Insets(0, 0, 0, 0), 0, 0);
int ind = 0;
int row = 3;
int column = 4;
for (int i = 0; i < row; i++) {
for (int j = 1; j < column; j++) {
gbc.gridx = j;
gbc.gridy = i;
pnlButton.add(arrayButton[ind++], gbc);
}
}
gbc.weightx = 0;
gbc.gridheight = 3;
gbc.gridx = 0;
gbc.gridy = 0;
pnlButton.add(btnLeft, gbc);
gbc.gridx = 4;
gbc.gridy = 0;
pnlButton.add(btnRight, gbc);
pnlButton.setPreferredSize(new Dimension(1000, 700));
return pnlButton;
}
public static void main(String[] args) {
new MyFrame();
}
}
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
导入java.awt.BorderLayout;
导入java.awt.ComponentOrientation;
导入java.awt.Dimension;
导入java.awt.GridBagConstraints;
导入java.awt.GridBagLayout;
导入java.awt.Insets;
导入javax.swing.*;
公共类MyFrame扩展了JFrame{
私有JButton[]阵列按钮=新JButton[9];
私有JButton btnLeft=新JButton(“”);
private JScrollPane scpButtons=new JScrollPane();
公共MyFrame(){
for(int i=0;i
编辑4
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
(希望是最后一个:-)
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
最终的罪魁祸首似乎是scrollPane的主视口:它在RToL中调整视图大小时会感到困惑,因为它曾经比首选视图小。没有跟踪到底出了什么问题,但看起来是可行的(除了在core中找到bug并推动snoracle进行修复;)解决方案是使视图实现可滚动,特别是实现
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
- getPreferredScrollableViewportSize返回getPreferredSize
- 如果高度/宽度小于父级高度/宽度,则实现GetScrollableTracksViewPerthweight/Width返回true,否则返回false
JXPanel(包含在中)是一个可滚动的,默认情况下会执行第一个操作,并且可以通过适当设置ScrollableSizeHints为后者进行配置:
private JPanel initPnlButton() {
JXPanel pnlButton = new JXPanel(new GridBagLayout());
pnlButton.setScrollableWidthHint(ScrollableSizeHint.PREFERRED_STRETCH);
pnlButton.setScrollableHeightHint(ScrollableSizeHint.PREFERRED_STRETCH);
...
}
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
有了这些,就不需要更多的粗线条了,只需在添加所有组件后应用CO即可:
applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
pack();
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
编辑2
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
我们(包括@Reza Gh和我)玩得越多,我就越倾向于将这种行为视为一种错误。总结我们的最新发现
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
- 滚动窗格似乎是罪魁祸首(Reza)
- 当面板的尺寸调整为/低于其首选尺寸时,这种不良行为就开始了(请注意,在创建面板时,arteficial-至少我希望它不是Reza生产代码的一部分-setPreferred)
编辑
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
再玩一点,在我看来,这是一种非常奇怪的实例化行为。要播放的片段(在实例化结束时)
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
和注释1、2或两者
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
- 注释二:框架以压缩大小出现,最大化它不会填充框架,但子框架停靠在右边缘
- 注释1:框架以最大化大小出现,子对象填充完成的内容,然后调整大小为打包并再次最大化:子对象不填充
- 评论2:frame的压缩大小接近(大一个像素),最大化(以及所有其他调整大小)正确填充屏幕
确切的行为可能也取决于本机组件方向(我的是LToR)。总的来说,我认为这是面向组件的核心处理中的一个bug(毫不奇怪,经过这么多年,它并不像我们预期的那样稳定)
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
看起来像是一个黑客左右调整大小(略为1像素左右,最大值单独不工作)后,一个包,然后调用applyCO
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
原创
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
这并没有解决最初的问题(即在框架实例化时应用componentOrientation),只演示了如何在运行时安全地切换CO
Action createCOToggle(final JFrame frame) {
Action toggleComponentOrientation = new AbstractAction("toggle orientation") {
@Override
public void actionPerformed(ActionEvent e) {
ComponentOrientation current = frame.getComponentOrientation();
if (current.isLeftToRight()) {
frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
} else {
frame.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
}
frame.getRootPane().revalidate();
frame.invalidate();
frame.validate();
frame.repaint();
}
};
return toggleComponentOrientation;
}
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
使用它配置动作感知组件将使框架按预期运行,即填充整个区域。许多re/in/validate看起来很奇怪,但事实证明是必要的(在jdk6中),正如我们在中所经历的那样
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
现在我的期望是,在框架的实例化结束时调用相同的操作也会使它正常工作,也就是说
.... // configure/fill frame
setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createCOToggle(MyFrame.this).actionPerformed(null);
}
});
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
不幸的是,事实并非如此。目前还不知道为什么,抱歉。在玩了很多属性并上下移动语句后,我找到了答案。
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
如果你把
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
之后
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
applycomponentation(组件方向:从右到左)代码>
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
一切正常,无需设置大小(getWidth()+1,getHeight()+1)代码>
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
有趣的是,我有一整天的时间:)c#或其他语言有这样的错误吗
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
如果让SwingUtilities
bloc运行,则在调整窗口大小之前,所有内容都是LtR
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class MyFrame extends JFrame {
private JButton[] arrayButton = new JButton[9];
private JButton btnLeft = new JButton("<");
private JButton btnRight = new JButton(">");
private JScrollPane scpButtons = new JScrollPane();
public MyFrame() {
for (int i = 0; i < arrayButton.length; i++)
arrayButton[i] = new JButton("btn");
JMenu mnuSettings = new JMenu("MENU");
JMenuBar menubar = new JMenuBar();
menubar.add(mnuSettings);
setJMenuBar(menubar);
JPanel pnlButton = initPnlButton();
scpButtons.setViewportView(pnlButton);
setLayout(new BorderLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(scpButtons, BorderLayout.CENTER);
pack();
// [1]
setExtendedState(JFrame.MAXIMIZED_BOTH);
//setSize(getWidth() + 1, getHeight() + 1);
// [2]
setVisible(true);
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
//here
scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
// }
// });
}
private JPanel initPnlButton() {
JPanel pnlButton = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, 10,
1, new Insets(0, 0, 0, 0), 0, 0);
int ind = 0;
int row = 3;
int column = 4;
for (int i = 0; i < row; i++) {
for (int j = 1; j < column; j++) {
gbc.gridx = j;
gbc.gridy = i;
pnlButton.add(arrayButton[ind++], gbc);
}
}
gbc.weightx = 0;
gbc.gridheight = 3;
gbc.gridx = 0;
gbc.gridy = 0;
pnlButton.add(btnRight, gbc);
gbc.gridx = 4;
gbc.gridy = 0;
pnlButton.add(btnLeft, gbc);
pnlButton.setPreferredSize(new Dimension(1000, 700));
return pnlButton;
}
public static void main(String[] args) {
new MyFrame();
}
导入java.awt.BorderLay