2016-09-19 47 views
0

如果我們拖動滾動條超過某個點,顯示的文本就會變得「清晰」。我手動將字符串放在遠端,以查看它是否可以顯示並且工作。爲什麼JPanel剪輯後的文本在某個點之後?

當我手動設置它時,它會從這些座標中正確繪製(如示例中所示),但在使用滾動條更改x座標時會剪輯)。

這是代碼:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.event.*; 

public class ScrollBarDemo2 extends JFrame { 
private MessagePanel messagePanel = new MessagePanel(); 
private JScrollBar jscbHorizontal = new JScrollBar(JScrollBar.HORIZONTAL); 
private JScrollBar jscbVertical = new JScrollBar(JScrollBar.VERTICAL); 
private JTextField jtfMessage = new JTextField("Example String"); 

public ScrollBarDemo2() { 
    // Add components to the frame 
    add(messagePanel, BorderLayout.CENTER); 
    add(jscbHorizontal, BorderLayout.SOUTH); 
    add(jscbVertical, BorderLayout.EAST); 
    add(jtfMessage, BorderLayout.NORTH); 

    // Register listener to scroll bars 
    ScrollBarListener jscbListener = new ScrollBarListener(); 
    jscbHorizontal.addAdjustmentListener(jscbListener); 
    jscbVertical.addAdjustmentListener(jscbListener); 

    // Register a listener in text field 
    jtfMessage.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      // Set the text in messagePanel to the given text 
      messagePanel.setText(e.getActionCommand()); 
     } 
    }); 
} 

private class ScrollBarListener implements AdjustmentListener { 
    @Override 
    public void adjustmentValueChanged(AdjustmentEvent e) { 
     // Determine the orientation of the event source 
     JScrollBar scrollBar = (JScrollBar)e.getAdjustable(); 

     if (scrollBar.getOrientation() == JScrollBar.HORIZONTAL) { 
      // Obtain the horizontal space remaining 
      double spaceAvailable = (double)messagePanel.getHorizontalEmptySpace(); 

      // Find how much to scale each value of the scroll bars (since we're using the default 100 total values) 
      double scaledValue = (scrollBar.getValue() * spaceAvailable/(double)scrollBar.getMaximum()); 

      // Set new x coordinate 
      messagePanel.setX((int)scaledValue); 
     } 
     else if (scrollBar.getOrientation() == JScrollBar.VERTICAL) { 
      // Obtain the vertical space remaining 
      double spaceAvailable = (double)messagePanel.getVerticalEmptySpace(); 

      // Find how much to scale each value of the scroll bars (since we're using the default 100 total values) 
      double scaledValue = (scrollBar.getValue()/(double)scrollBar.getMaximum()) * spaceAvailable; 

      // Set new x coordinate 
      messagePanel.setY((int)scaledValue); 
     } 
    } 
} 

/** main method **/ 
public static void main(String[] args) { 
    ScrollBarDemo2 frame = new ScrollBarDemo2(); 
    frame.setSize(500, 200); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
} 
} 

class MessagePanel extends JPanel { 
    private FontMetrics fm; 
    private String message = ""; 
    private int messageX = -1; 
    private int messageY = -1; 

    public MessagePanel() { 
     this("Welcome to Java"); 
    } 

    public MessagePanel(String message) { 
     this.message = message; 
    } 

    public void moveRight() { 
     messageX += getWidth()/50; 
     repaint(); 
    } 

    public void moveLeft() { 
     messageX -= getWidth()/50; 
     repaint(); 
    } 

    public void moveUp() { 
     messageY -= getHeight()/100; 
     repaint(); 
    } 

    public void moveDown() { 
     messageY += getHeight()/100; 
     repaint(); 
    } 

    public int getX() { 
     return messageX; 
    } 

    public int getY() { 
     return messageY; 
    } 

    public void setX(int x) { 
     messageX = x; 
     repaint(); 

    } 

    public void setY(int y) { 
     messageY = y; 
     repaint(); 
    } 

    public void setText(String newMessage) { 
     message = newMessage; 
     repaint(); 
    } 

    public int getVerticalEmptySpace() { 
     return getHeight() - fm.getAscent(); 
    } 

    public int getHorizontalEmptySpace() { 
     return getWidth() - fm.stringWidth(message); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     if (messageX < 0 && messageY < 0) {  // Check to initialize centered position 
      fm = g.getFontMetrics(); 

      messageX = getWidth() - fm.stringWidth(message); // Manually setting it to the very end coordinate 
      messageY = getHeight()/2 - fm.getAscent()/2; 
     } 

     g.drawString(message, messageX, messageY); 

    } 
} 
+0

'非常感謝您的回答和可運行代碼! ' - 我給你解決了你的問題。你所需要做的就是重命名方法,並且你可以運行。我們不是在這裏爲你寫代碼,而是給你提供解決問題所需的信息。 – camickr

+0

我明白了,但我被告知要「接受」,不幸的是我們只能「接受」一個,即使你給出了一個完全簡潔和簡潔的答案,這些答案完全顯示了我做錯了什麼以及我需要注意什麼。我沒有在尋找有人專門投入他們的專業知識和時間,所以我只是被吉爾伯特的答案所淹沒,並且儘管評論指導說不要這樣寫了一個「感謝」。一如既往,我非常感謝您和社區在這裏爲我的問題提供了許多優秀的答案和代碼審查。 – Legate

+0

'我被告知要「接受」,不幸的是我們只能「接受」一個,即使你給出了一個非常簡潔和簡潔的答案,這些答案完全顯示了我做錯了什麼以及我需要注意什麼。「 - 好像它看起來似乎這是你應該接受的答案。這是第一個指出問題並提供解決方案的答案,但你仍然沒有表示感謝。 「一如既往,我非常感謝你和社區 - 通常你也會花時間感謝所有提出建議的人。而且,在你發佈的第一個問題上,你也沒有感謝任何人。 – camickr

回答

2

我對代碼做了一些更改。這是我創建的GUI。

Scroll Bar Test

  1. 我格式化你的代碼。

  2. 我把你的Swing代碼封裝在Runnable中,所以我可以使用SwingUtilities invokeLater方法在Event Dispatch thread上啓動你的Swing應用程序。 Oracle和我堅持所有的Swing應用程序都從Event Dispatch線程開始。

  3. 正如camickr在他的回答中所說的,你意外地超過了JPanel的getX,getY,setX和setY方法。我重命名了你的方法。

  4. 我使用底層JTextField Document的動作監聽器,以便在JTextField中輸入的任何內容都可以在JPanel上繪製。

將messageX設置爲小於零仍然存在問題。我要讓你解決這個問題。

這裏是更正的代碼。

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.event.AdjustmentEvent; 
import java.awt.event.AdjustmentListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollBar; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

public class ScrollBarDemo2 extends JFrame { 
    private static final long serialVersionUID = -3189856074534869132L; 

    private JScrollBar jscbHorizontal = new JScrollBar(JScrollBar.HORIZONTAL); 
    private JScrollBar jscbVertical = new JScrollBar(JScrollBar.VERTICAL); 

    private JTextField jtfMessage = new JTextField("Example String"); 

    private MessagePanel messagePanel = new MessagePanel(jtfMessage.getText()); 

    public ScrollBarDemo2() { 
     // Add components to the frame 
     add(messagePanel, BorderLayout.CENTER); 
     add(jscbHorizontal, BorderLayout.SOUTH); 
     add(jscbVertical, BorderLayout.EAST); 
     add(jtfMessage, BorderLayout.NORTH); 

     // Register listener to scroll bars 
     ScrollBarListener jscbListener = new ScrollBarListener(); 
     jscbHorizontal.addAdjustmentListener(jscbListener); 
     jscbVertical.addAdjustmentListener(jscbListener); 

     // Register a listener in text field 
     jtfMessage.getDocument().addDocumentListener(new DocumentListener() { 
      @Override 
      public void insertUpdate(DocumentEvent e) { 
       messagePanel.setText(jtfMessage.getText()); 
      } 

      @Override 
      public void removeUpdate(DocumentEvent e) { 
       messagePanel.setText(jtfMessage.getText()); 
      } 

      @Override 
      public void changedUpdate(DocumentEvent e) { 
       messagePanel.setText(jtfMessage.getText()); 
      } 
     }); 

    } 

    private class ScrollBarListener implements AdjustmentListener { 
     @Override 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      // Determine the orientation of the event source 
      JScrollBar scrollBar = (JScrollBar) e.getAdjustable(); 

      if (scrollBar.getOrientation() == JScrollBar.HORIZONTAL) { 
       // Obtain the horizontal space remaining 
       double spaceAvailable = (double) messagePanel 
         .getHorizontalEmptySpace(); 

       // Find how much to scale each value of the scroll bars (since 
       // we're using the default 100 total values) 
       double scaledValue = (scrollBar.getValue() * spaceAvailable/(double) scrollBar 
         .getMaximum()); 

       // Set new x coordinate 
       messagePanel.setMessageX((int) scaledValue); 
      } else if (scrollBar.getOrientation() == JScrollBar.VERTICAL) { 
       // Obtain the vertical space remaining 
       double spaceAvailable = (double) messagePanel 
         .getVerticalEmptySpace(); 

       // Find how much to scale each value of the scroll bars (since 
       // we're using the default 100 total values) 
       double scaledValue = (scrollBar.getValue()/(double) scrollBar 
         .getMaximum()) * spaceAvailable; 

       // Set new x coordinate 
       messagePanel.setMessageY((int) scaledValue); 
      } 
     } 
    } 

    /** main method **/ 
    public static void main(String[] args) { 
     Runnable runnable = new Runnable() { 
      @Override 
      public void run() { 
       ScrollBarDemo2 frame = new ScrollBarDemo2(); 
       frame.setTitle("Scroll Bar Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }; 
     SwingUtilities.invokeLater(runnable); 
    } 
} 

class MessagePanel extends JPanel { 
    private static final long serialVersionUID = -2743160276473942475L; 

    private FontMetrics fm; 
    private String message = ""; 
    private int messageX = -1; 
    private int messageY = -1; 

    public MessagePanel() { 
     this("Welcome to Java"); 
    } 

    public MessagePanel(String message) { 
     this.message = message; 
     this.setPreferredSize(new Dimension(500, 200)); 
    } 

    public void moveRight() { 
     messageX += getWidth()/50; 
     repaint(); 
    } 

    public void moveLeft() { 
     messageX -= getWidth()/50; 
     repaint(); 
    } 

    public void moveUp() { 
     messageY -= getHeight()/100; 
     repaint(); 
    } 

    public void moveDown() { 
     messageY += getHeight()/100; 
     repaint(); 
    } 

    public int getMessageX() { 
     return messageX; 
    } 

    public int getMessageY() { 
     return messageY; 
    } 

    public void setMessageX(int x) { 
     messageX = x; 
     repaint(); 

    } 

    public void setMessageY(int y) { 
     messageY = y; 
     repaint(); 
    } 

    public void setText(String newMessage) { 
     message = newMessage; 
     repaint(); 
    } 

    public int getVerticalEmptySpace() { 
     return getHeight() - fm.getAscent(); 
    } 

    public int getHorizontalEmptySpace() { 
     return getWidth() - fm.stringWidth(message); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     if (messageX < 0 && messageY < 0) { // Check to initialize centered 
              // position 
      fm = g.getFontMetrics(); 

      messageX = getWidth() - fm.stringWidth(message); // Manually setting 
                   // it to the 
                   // very end 
                   // coordinate 
      messageY = getHeight()/2 - fm.getAscent()/2; 
     } 

     g.drawString(message, messageX, messageY); 

    } 
} 
+0

非常感謝您的答案和可運行代碼! – Legate

1

getX()getYJComponent類的方法,你不應該覆蓋它們。

重命名方法,可能類似於getMessageX()和getMessageY()。您還應該重命名setX()和setY()方法,使其與您選擇的任何獲取方名稱保持一致。

相關問題