2011-03-26 68 views
1

這是我第四個問題,在大約兩週內......我想我有很多東西要學。擺動組件相互繪製

無論如何,我希望下面編寫的示例能夠比我更好地解釋問題,但是由於我將所有組件都更改爲Swing而不是AWT,因此它們都在繪製每個組件每當我調用repaint()時,它們自己在面板內。

這段代碼本質上是我的程序,盡我所能剝離下來,而不會完全破壞問題。我在那裏插入了一些自定義列表框組件來演示該問題,並將邊框設爲紅色,以便更輕鬆地查看繪圖的位置。

Test.java:

package test; 

import java.awt.image.*; 
import java.awt.*; 
import javax.swing.*; 
import java.io.*; 
import javax.imageio.*; 
import java.util.*; 

public class Test extends JFrame 
{ 
    public static void main(String[] args) 
    {   
     Test test1 = new Test(); 
    } 

    public Test() 
    { 
     super("Test Frame"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
     setVisible(true); 
     setSize(800, 480); 
     setLocationRelativeTo(null); 

     loadTestScreen(); 
    } 

    public void loadTestScreen() 
    { 
     TestScreen newTestScreen = new TestScreen(); 
     newTestScreen.setSize(new Dimension(getWidth() - getInsets().left - getInsets().right, getHeight() - getInsets().top - getInsets().bottom)); 
     setContentPane(newTestScreen); 
    } 

} 

TestScreen.java:

package test; 

import java.awt.image.*; 
import java.awt.*; 
import javax.swing.*; 
import java.io.*; 
import javax.imageio.*; 
import java.awt.event.ComponentListener; 
import java.awt.event.ComponentEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseEvent; 
import java.util.*; 
import java.net.URI; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

public class TestScreen extends JPanel implements ComponentListener, MouseListener 
{ 
    int border, LT; 

    public TestScreen() 
    { 
     setLayout(null); 
     setOpaque(true); 
     setBackground(Color.WHITE); 
     addComponentListener(this); 

     border = 8; 
     LT = 4; 

     /////////////////////////////////////////////////////////// 

     ArrayList<String> testList = new ArrayList<String>(); 
     testList.add("1"); 
     testList.add("2"); 
     testList.add("3"); 
     testList.add("4"); 
     testList.add("5"); 
     testList.add("6"); 

     add(new ListBox(testList), 0); 
     add(new ListBox(testList), 1); 
    } 

    public void paintComponent(Graphics g) 
    { 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.setStroke(new BasicStroke((float)(LT))); 

     g2d.setColor(new Color(255, 0, 0)); 
     g2d.drawRoundRect(border, border, getWidth() - border - border, getHeight() - border - border, border + border, border + border); 
    } 


    public void componentHidden(ComponentEvent e){} 
    public void componentShown(ComponentEvent e){} 
    public void componentMoved(ComponentEvent e) 
    { 
     componentResized(e); 
    } 
    public void componentResized(ComponentEvent e) 
    {  
     getComponent(0).setLocation(20, 20); 
     getComponent(0).setSize(100, 100); 

     getComponent(1).setLocation(200, 200); 
     getComponent(1).setSize(150, 150); 

     repaint(); 
    } 

    public void mouseEntered(MouseEvent e) 
    { 
      repaint(); 
    } 
    public void mouseExited(MouseEvent e) 
    { 
      repaint(); 
    } 

    public void mouseReleased(MouseEvent e){} public void mouseDragged(MouseEvent e){} public void mouseClicked(MouseEvent e){} 

    public void mousePressed(MouseEvent e) 
    { 
     repaint(); 
    } 
} 

ListBox.java:

package test; 

import java.beans.*; 
import java.util.*; 
import java.awt.*; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseWheelListener; 
import java.awt.event.MouseWheelEvent; 
import java.awt.event.MouseMotionListener; 
import java.awt.event.ComponentListener; 
import java.awt.event.ComponentEvent; 
import java.beans.PropertyChangeSupport; 
import javax.swing.*; 

public class ListBox extends JComponent implements MouseListener, MouseMotionListener, MouseWheelListener, ComponentListener 
{ 
    public ArrayList<String> data; 
    int border, LT; 
    int selectedIndex = 0; 
    int mousedIndex = -1; 
    public int viewedHeight = 0; 
    int itemHeight; 
    int numberOfDisplayedItems; 
    Font miniFont; 
    FontMetrics miniMetrics; 
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); 

    public ListBox(ArrayList<String> list) 
    { 
     setVisible(true); 
     setOpaque(true); 

     border = 8; 
     LT = 4; 

     addMouseListener(this); 
     addMouseMotionListener(this); 
     addComponentListener(this); 
     addMouseWheelListener(this); 

     data = list; 
     miniFont = new Font("Calibri", Font.PLAIN, 15); 
     miniMetrics = getFontMetrics(miniFont); 

     itemHeight = miniMetrics.getAscent() + miniMetrics.getDescent() + border + border; 
    } 

    public void paintComponent(Graphics g) 
    { 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.setColor(new Color(93, 138, 168)); 
     g2d.setStroke(new BasicStroke((float)LT/2)); 
     g2d.setClip(-(LT/2), -(LT/2), getWidth() + LT, getHeight() + LT); 

     int cumulativeDist = -viewedHeight; 

     for (int i = 0; i < data.size(); i++) 
     { 
      if (selectedIndex == i) 
       g2d.fillRect(0, cumulativeDist, getWidth(), itemHeight); 

      cumulativeDist += itemHeight; 
      g2d.drawLine(0, cumulativeDist, getWidth(), cumulativeDist); 
     } 
     g2d.drawRect(0, 0, getWidth(), getHeight()); 

     g2d.setFont(miniFont); 
     g2d.setColor(new Color(42, 60, 76)); 

     cumulativeDist = -viewedHeight + border + miniMetrics.getAscent(); 

     for (int i = 0; i < data.size(); i++) 
     { 
      if (mousedIndex == i){ 
      g2d.drawString(data.get(i), border + border/2, cumulativeDist); 
      } else { 
      g2d.drawString(data.get(i), border, cumulativeDist); 
      } 

      cumulativeDist += itemHeight; 
     } 

    } 

    public String getSelectedItem() 
    { 
     return data.get(selectedIndex); 
    } 
    public void mouseReleased(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseDragged(MouseEvent e){}public void mouseClicked(MouseEvent e){} 

    public void mousePressed(MouseEvent e) 
    { 
     int old = selectedIndex; 
     int mouseHeight = viewedHeight + e.getY(); 
     int ID = mouseHeight/itemHeight; 
     System.out.println(mouseHeight/itemHeight); 
     selectedIndex = ID; 
     pcs.firePropertyChange("selectedIndex", old, selectedIndex); 
    } 

    public void componentHidden(ComponentEvent e){} public void componentShown(ComponentEvent e){} public void componentMoved(ComponentEvent e){} 
    public void componentResized(ComponentEvent e) 
    { 
     numberOfDisplayedItems = (int)((getHeight()/itemHeight) + 0.5); 
     repaint(); 
    } 

    public void mouseWheelMoved(MouseWheelEvent e) 
    { 
     if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) 
     { 
      if (e.getUnitsToScroll() > 0) 
      { 
      viewedHeight += itemHeight; 
      }else{ 
      viewedHeight -= itemHeight; 
      } 

      if (viewedHeight > (data.size() * itemHeight) - getHeight()) 
       viewedHeight = (data.size() * itemHeight) - getHeight(); 

      if (viewedHeight < 0) 
      { 
       viewedHeight = 0; 
      } 

      mouseMoved((MouseEvent)e); 

      repaint(); 
     } 
    } 

    public void mouseMoved(MouseEvent e) 
    { 
     int mouseHeight = viewedHeight + e.getY(); 
     int ID = mouseHeight/itemHeight; 
     mousedIndex = ID; 
     repaint(); 
    } 

    public void mouseExited(MouseEvent e) 
    { 
     mousedIndex = -1; 
     repaint(); 
    } 
} 

謝謝,一nd如果在編程中發現其他任何明顯的問題,請不要猶豫,告訴我:P

+0

你應該添加一些關於你的意思是「繪圖問題」的描述 – 2011-03-26 18:26:32

+0

@Bala:我會試試,但我不知道問題是什麼。 – Tharwen 2011-03-26 18:31:41

+0

+1 [sscce](http://sscce.org/)。爲了簡潔起見,考慮一個公共類,然後是任何必需的非公共類,例如[http://stackoverflow.com/questions/3420651]。 – trashgod 2011-03-27 14:04:29

回答

3

ListBox中的即時問題 - 繪畫僞影 - 是由於不尊重opaque property而引起的。使用true承諾繪製所有位,但您的paintComponent()未能這樣做。

這裏有幾個建議:

  1. 不要忽視event dispatch thread

  2. 請使用event listeners,但也要考慮可用的適配器,它們具有方便的null實現。

  3. 不要重新創建existing components,並且僅作爲最後的手段覆蓋paintComponent()

  4. 是否學會使用layout managersborders

是的,有很多東西需要學習,但這種實驗是無價的。

+0

所以我需要繪製列表框背景呢?好。那些其他的東西讓我覺得自己像個小孩子,儘管......我有很多閱讀要做。 – Tharwen 2011-03-27 12:35:56

+0

嘗試每個看看效果:'setOpaque(false)'或'fillRect()'。 – trashgod 2011-03-27 13:55:47

1

只有在構建器的最後設置組件後,才應該調用setVisible(true);