2012-08-26 77 views
4

我有9个jbuttons添加到jpanel和面板添加到jscrollpane并将其添加到jframe。从右到左的方向无关的按钮尺寸变化

http://www.pic1.iran-forum.ir/images/up9/95426323683658592564.jpg

当我通过改变框的方向: applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

面板移动到右侧和按钮的尺寸得到了固定,wouldn`t填充面板,但你在图片中看到低于scrolbar是填充面板

http://www.pic1.iran-forum.ir/images/up9/60975202722295688553.jpg

的所有宽度(我用的GridBagLayout添加按钮和borderlayout.center为附加滚动面板)。

是在java中的错误还是?编辑: 其最简单的看法。它有帮助吗?

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(); 
} 
} 
+2

...或者你正在做的事情错了?那么,我会猜测后面的。作为一个建议,考虑发布你的代码的相关部分,或者甚至更好的代码 – Sujay

+0

的[SSCCE](http://sscce.org/)版本@sujay这里是sscce-so? –

+0

1)人们不会收到关于编辑问题的通知。 2)@Sujay没有答应解决问题,只是提供了一些很好的建议。 3)好的SSCCE,+1。 :) –

回答

1

玩过很多属性并上下移动语句后,我发现答案。 如果你把

scpButtons.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 

applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

一切都会好起来的,并没有必要setSize(getWidth() + 1, getHeight() + 1);

太好笑从我这得到了whle一天:)做C#或其他LANGS有这样的错误?

如果你让SwingUtilities集合运行,为了调整窗口的大小,所有的东西都是LtR。

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(); 
    } 

}

+0

哦,我失去了2的声望,因为不接受最后一个答案:( 请有人投我的答案 thanx before;) –

+0

好,你发现一个似乎没问题的黑客 - 虽然我怀疑fullfils的RToL要求:有scrollPane在LToR导致不正确的水平滚动(零仍然在左边,而不是右边) – kleopatra

+0

嗯..你/客户不介意水平滚动发生错误的方向? – kleopatra

4

编辑4

(希望的最后:-)

最终的罪魁祸首似乎是ScrollPane的主视口:在RTOL一旦浆纱其观点,当它变得迷茫它比它的首选要小。没有跟踪究竟是什么出了问题,但看起来像一个可行的(短发现在核心的bug和微调snoracle到固定它;)的解决方案是使视图实现Scrollablable,具体实施

  • getPreferredScrollableViewportSize返回的getPreferredSize
  • 实施getScrollableTracksViewportHeight /宽度如果高度/宽度小于母体高度/宽度和假返回真,否则

JXPanel(包含在SwingX)是-一个可滚动,其所做的第一默认并且可以是通过设置Sc为后者配置适当rollableSizeHints:

private JPanel initPnlButton() { 
    JXPanel pnlButton = new JXPanel(new GridBagLayout()); 
    pnlButton.setScrollableWidthHint(ScrollableSizeHint.PREFERRED_STRETCH); 
    pnlButton.setScrollableHeightHint(ScrollableSizeHint.PREFERRED_STRETCH); 
    ... 
} 

随着到位,没有进一步需要的哈克线,简单地添加所有成分后应用CO:

applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 
pack(); 
setExtendedState(JFrame.MAXIMIZED_BOTH); 
setVisible(true); 

编辑2

越是( @Reza Gh和我)玩选项越多,我倾向于将行为视为一个错误。总结我们的最新调查结果

  • 滚动面板似乎是一大主因(礼)一旦专家组已经在被调整/其首选大小低于
  • 不当行为开始(注意arteficial - 至少我希望它是不是礼的生产代码的一部分 - 创建面板时setPreferred)

编辑

打多一点,在我看来就像一个实例很怪异的行为。一个片段一起玩(在实例化结束)

pack(); 
// [1] 
setSize(getWidth() + 1, getHeight() + 1); 
// [2] 
setExtendedState(JFrame.MAXIMIZED_BOTH); 
setVisible(true); 
SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 
    } 
}); 

和注释1,2或两者

  • 评论都:框出现在包装的大小,最大化它不填写框架,但孩子停靠在右边缘
  • 评论1:帧出现在最大化的大小,子填充完成的内容,然后调整大小打包并再次最大化:子不填充
  • 评论2:帧出现近(一个像素更大)包装尺寸,最大化(和所有其他调整大小)正确填充屏幕

确切的行为可能还取决于本地组件方向(我的LToR)。总体而言,我认为这是组件定位核心处理中的一个漏洞(不出意外,它不像我们预期的那么稳定)。

看起来像一个黑客周围是一个包后,调整大小(略微大约1像素,最大独自不起作用),然后调用applyCO。

原始

这并不解决原来的问题(这是施加在所述框架的实例化的ComponentOrientation)中,仅展示了如何安全地切换在运行时

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; 
} 

CO配置具有动作感知的组件,将使框架按预期运行,即填满整个区域。许多重/中/只会验证看起来很怪异 - 但竟然是必要的(在JDK6)正如我们在SwingX test coverage

经历现在我的期望本来,这调用同样的动作在帧的实例的结束将使表现也一样,那就是

.... // configure/fill frame 
setVisible(true); 
SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     createCOToggle(MyFrame.this).actionPerformed(null); 
    } 
}); 

不幸的是,事实并非如此。目前没有线索为什么不,对不起。

+0

Althogh理解你的答案对我来说很难!(谢谢你)谢谢你。现在我确定没有对我的解决方案:(谢谢 –

+0

好吧,我明白了,但为什么在运行时切换 - 我需要整个我的程序从开始到结束RtL - 没有切换需要 –

+0

总有一个解决方案, t绝望:-)看到我的编辑为黑客(可能或不可能总是工作,不保证) – kleopatra