2014-12-05 31 views
0

这里是我的简单的例子:的JScrollBar的setValue不工作时,对话框不可见

import java.awt.BorderLayout; 
import java.awt.Dialog; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.util.ArrayList; 
import java.util.Enumeration; 

import javax.swing.AbstractButton; 
import javax.swing.ButtonGroup; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.EmptyBorder; 
import javax.swing.JScrollPane; 
import javax.swing.JRadioButton; 

import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 

public class SelectItem extends JDialog { 
    private static final long serialVersionUID = 1L; 
    private final JPanel contentPanel = new JPanel(); 
    private String item; 
    private ButtonGroup group; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     final JFrame frame = new JFrame(); 
     frame.setBounds(100, 100, 133, 102); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().setLayout(new BorderLayout(0, 0)); 

     JButton btnSelectItem = new JButton("select item"); 
     btnSelectItem.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       ArrayList<String> items = new ArrayList<String>(); 
       for (char c = 'A'; c <= 'Z'; c++) 
        items.add(String.valueOf(c)); 
       SelectItem dialog = new SelectItem(frame, items, items.get(20)); 

       System.out.println("Item = " + dialog.showChooseDialog()); 
      } 
     }); 
     frame.getContentPane().add(btnSelectItem); 
     frame.setVisible(true); 
    } 

    public String showChooseDialog(){ 
     setVisible(true); 
     return item; 
    } 

    /** 
    * Create the dialog. 
    */ 
    public SelectItem(JFrame parent, ArrayList<String> items, String selectedItem) { 
     super(parent, null, Dialog.ModalityType.DOCUMENT_MODAL); 
     setTitle("Select Item"); 
     setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 

     setBounds(100, 100, 450, 300); 
     getContentPane().setLayout(new BorderLayout()); 
     contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     getContentPane().add(contentPanel, BorderLayout.CENTER); 
     contentPanel.setLayout(null); 

     JScrollPane scrollPane = new JScrollPane(); 
     scrollPane.setBounds(0, 0, 434, 228); 
     contentPanel.add(scrollPane); 

     JPanel panel = new JPanel(); 
     scrollPane.setViewportView(panel); 
     panel.setLayout(null); 

     int marginX = 6; 
     int currentY = 7; 
     int width = 420; 
     int height = 23; 
     int paddingY = 26; 
     int scrollY = 0; 
     group = new ButtonGroup(); 

     for (String str: items){ 
      JRadioButton rd = new JRadioButton(str); 
      rd.setBounds(marginX, currentY, width, height); 
      currentY = currentY + paddingY; 
      panel.add(rd); 
      group.add(rd); 

      if (str == selectedItem){ //or str.equals()... 
       group.setSelected(rd.getModel(), true); 
       //scrollY = rd.getY() - height/2 - scrollPane.getHeight()/2; 
       scrollY = rd.getY() + height/2 - scrollPane.getHeight()/2; 
      } 
     } 
     System.out.println("ScrollY: " + scrollY); 

     Dimension size = panel.getPreferredSize(); 
     size.setSize(size.getWidth(), currentY); 
     panel.setPreferredSize(size); 
     //this.setVisible(true); 
     scrollPane.getVerticalScrollBar().setValue(scrollY); 

     panel.repaint(); 
     panel.revalidate(); 
     scrollPane.getVerticalScrollBar().repaint(); 
     scrollPane.getVerticalScrollBar().revalidate(); 
     scrollPane.repaint(); 
     scrollPane.revalidate(); 
     this.repaint(); 
     this.revalidate(); 

     { 
      JPanel buttonPane = new JPanel(); 
      buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); 
      getContentPane().add(buttonPane, BorderLayout.SOUTH); 
      { 
       JButton okButton = new JButton("OK"); 
       okButton.addActionListener(new ActionListener() { 
        public void actionPerformed(ActionEvent e) { 
         Enumeration<AbstractButton> iter = group.getElements(); 

         while (iter.hasMoreElements()){ 
          AbstractButton rd = iter.nextElement(); 
          if (group.isSelected(rd.getModel())){ 
           item = rd.getActionCommand(); 
           break; 
          } 
         } 
         //System.out.println(group.getSelection().getActionCommand()); 
         setVisible(false); 
         dispose(); 
        } 
       }); 
       okButton.setActionCommand("OK"); 
       buttonPane.add(okButton); 
       getRootPane().setDefaultButton(okButton); 
      } 
      { 
       JButton cancelButton = new JButton("Cancel"); 
       cancelButton.addActionListener(new ActionListener() { 
        public void actionPerformed(ActionEvent e) { 
         item = null; 
         setVisible(false); 
         dispose(); 
        } 
       }); 
       cancelButton.setActionCommand("Cancel"); 
       buttonPane.add(cancelButton); 
      } 
     } 
    } 
} 

我创建的字符串列表,然后将其与default string value,或selectedItem在我的代码传递给一个JDialog的构造。
该对话框将显示列表中的所有项目并让用户选择一个。
这是通过使用JRadioButton完成的,并且JRadioButton对象的值等于default value将被默认选中。

一切工作正常。但是我想在对话框打开时自动将面板滚动到该单选按钮,该单选按钮将处于垂直对齐的中间。
像这样:
enter image description here

if (str == selectedItem){ //or str.equals()... 
    group.setSelected(rd.getModel(), true); 
    scrollY = rd.getY() + height/2 - scrollPane.getHeight()/2; 
} 
... 
scrollPane.getVerticalScrollBar().setValue(scrollY); 

但是当对话框打开时,它不会滚动到该位置。
我知道某些东西没有被更新,因为对话框不可见。
尝试增加

this.setVisible(true); 
更新前

滚动条,对话框将开放两次,在第二次,它是我想要正确显示。
但我仍然不知道如何解决这个问题。
任何人都可以帮助我。谢谢。 (对不起我的语法错误)

+0

帮助,请... – phibao37 2014-12-05 14:33:54

回答

1

首先:

  1. 摆脱所有重绘()和重新验证()方法。您需要使用这些方法的唯一时间是从可见GUI中添加/删除组件。在这种情况下,订单是revalidate()(调用布局管理器),然后是repaint()(以在那里绘制新的大小/位置的组件)。

  2. 摆脱零布局。当您使用布局管理器并且每个组件确定它自己的大小时,滚动效果会更好。

关于你提到的问题对滚动条的最大值只有100,在你执行你的代码,所以你不能将值设置为240。我猜想这是时间,因为你没有使用包()方法,然后使其可见。您应该能够在pack()后面设置滚动条的值。

或者,也许更好的方法是使用panel.scrollRectToVisible(....)。即使你不打包()对话框,这似乎也可以工作。

+0

感谢您的帮助。我使用scrollRectToVisible(...),它工作正常。 – phibao37 2014-12-05 16:37:58

+0

我无法实现JDialog.pack()工作 - 'contentPanel.setPreferredSize(新尺寸(434,228));' ... -'setValue(scrollY);' ... '这.pack();' 'setVisible(true);' 这不行。你可以给一些代码吗?谢谢 – phibao37 2014-12-05 16:44:38