2015-05-02 188 views
4

當JSlider上的標籤表在這些值發生更改時,不會根據滑塊的最小值和最大值進行更新。當getMinimum()和getMaximum()方法返回正確的值時,最小值/最大值會正確更新。滑塊下方的自動標籤顯示不正確的值。Java Swing滑塊標籤不根據滑塊最小/最大值進行更新

下面是這個問題的一個獨立的例子。代碼主要由Eclipse窗口構建器/ Swing設計器自動生成。

按下滑塊兩側的按鈕可更改滑塊的最大值。

import java.awt.EventQueue; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

import java.awt.BorderLayout; 

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

import javax.swing.JButton; 
import javax.swing.JSlider; 
import javax.swing.JLabel; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class SliderTrouble implements ActionListener 
{ 

    private JFrame frame; 
    private JSlider slider; 
    private JLabel lblMin; 
    private JLabel lblMax; 
    private JLabel lblCurrent; 
    private int sliderMax = 100; 
    private int sliderMajorSpacing = sliderMax/4; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       try 
       { 
        SliderTrouble window = new SliderTrouble(); 
        window.frame.setVisible(true); 
       } catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the application. 
    */ 
    public SliderTrouble() 
    { 
     initialize(); 
    } 

    /** 
    * Initialize the contents of the frame. 
    */ 
    private void initialize() 
    { 
     frame = new JFrame(); 
     frame.setTitle("Slider problems"); 
     frame.setBounds(100, 100, 481, 122); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().setLayout(new BorderLayout(0, 0)); 

     JPanel panel = new JPanel(); 
     frame.getContentPane().add(panel, BorderLayout.CENTER); 

     JButton btnNewButton = new JButton("100"); 
     btnNewButton.setBounds(10, 22, 64, 23); 
     btnNewButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       System.out.println("Pressed 100. Since this is the default value, everything is ok."); 
       sliderMax = 100; 
       sliderMajorSpacing = sliderMax/4; 
       changeSlider(sliderMax, sliderMajorSpacing); 
      } 
     }); 
     panel.setLayout(null); 
     panel.add(btnNewButton); 

     class SliderListener implements ChangeListener 
     { 
      public void stateChanged(ChangeEvent e) 
      { 
       JSlider slider = (JSlider) e.getSource(); 
       if (slider.getValueIsAdjusting()) 
       { 
        updateCurrent(slider.getValue()); 
       } 
      } 
     } 

     slider = new JSlider(); 
     slider.setBounds(79, 11, 300, 45); 
     slider.setMajorTickSpacing(sliderMajorSpacing); 
     slider.setPaintTicks(true); 
     slider.setPaintLabels(true); 
     slider.setMaximum(sliderMax); 
     slider.addChangeListener(new SliderListener()); 
     panel.add(slider); 

     JButton btnNewButton_1 = new JButton("196"); 
     btnNewButton_1.setBounds(389, 22, 62, 23); 
     btnNewButton_1.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       System.out.println("Pressed 196. The actual minimum and maximum values are updated correctly. getValue gets the correct value. The little gray tick lines are not updated accordingly. The text labels are done according to the default (button '100') settings, showing a max at 175 instead of 196. 175 is the closest multiple of 25 (which is the default major tick space)."); 
       sliderMax = 196; 
       sliderMajorSpacing = sliderMax/4; 
       changeSlider(sliderMax, sliderMajorSpacing); 
      } 
     }); 

     panel.add(btnNewButton_1); 

     JPanel panel_1 = new JPanel(); 
     frame.getContentPane().add(panel_1, BorderLayout.SOUTH); 

     JLabel lblSliderMin = new JLabel("Slider min:"); 
     panel_1.add(lblSliderMin); 

     lblMin = new JLabel(); 
     lblMin.setText(String.valueOf(slider.getMinimum())); 
     panel_1.add(lblMin); 

     JLabel lblMax_1 = new JLabel("max:"); 
     panel_1.add(lblMax_1); 

     lblMax = new JLabel(); 
     lblMax.setText(String.valueOf(slider.getMaximum())); 
     panel_1.add(lblMax); 

     JLabel lblCur = new JLabel("current:"); 
     panel_1.add(lblCur); 

     lblCurrent = new JLabel(); 
     lblCurrent.setText(String.valueOf(slider.getValue())); 
     panel_1.add(lblCurrent); 

     //frame.pack(); 
    } 

    private void changeSlider(int max, int majspace) 
    { 
     slider.setMajorTickSpacing(majspace); 
     slider.setMaximum(max); 

     System.out.println("max: " + max + " major: " + sliderMajorSpacing); 

     updateText(slider.getMinimum(), slider.getMaximum(), slider.getValue()); 
    } 

    private void updateText(int minimum, int maximum, int value) 
    { 
     lblMin.setText(String.valueOf(minimum)); 
     lblMax.setText(String.valueOf(maximum)); 
     lblCurrent.setText(String.valueOf(value)); 
    } 

    private void updateCurrent(int value) 
    { 
     lblCurrent.setText(String.valueOf(value)); 
    } 

    public void actionPerformed(ActionEvent arg0) 
    { 
    } 
} 
+0

你會期望標籤顯示什麼?滴答間隔爲25,所以可以顯示的最大值爲196,長度範圍爲175。 – kiheru

+0

主要滴答間距在changeSlider方法中發生變化,當按下其中一個按鈕時會調用該方法。我希望標籤在滴答間距變化時改變。 –

回答

5

貌似setMajorTickSpacing()上具有前一組標籤的滑塊調用時,實際上並沒有任何更新。這可以通過致電

slider.setLabelTable(null); 

在將新的刻度間距設置爲強制重新創建標籤之前解決。

+0

我可以發誓我試過了。這解決了這個問題。謝謝。 –