2016-09-19 44 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()方法,使其与您选择的任何获取方名称保持一致。

相关问题