这是我在大约两周内的第四个问题......我想我还有很多需要学习的地方。
无论如何,我希望我在下面准备的样本能够比我更好地解释问题,但是因为我将所有组件都改为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();
}
}
谢谢,如果您在我的编程中发现任何其他明显的问题,请不要犹豫告诉我:P
答案 0 :(得分:3)
ListBox
中的直接问题 - 绘画工件 - 是由于不尊重opaque property造成的。使用true
promises绘制所有位,但paintComponent()
未能这样做。
以下是一些建议:
请使用event listeners,还要考虑可用的适配器,这些适配器具有方便的空实现。
请勿重新发明existing components,并仅作为最后手段覆盖paintComponent()
。
请务必使用layout managers和borders。
是的,有很多值得学习的东西,但这种实验非常宝贵。
答案 1 :(得分:1)
只有在构造函数结束时设置组件后,才应调用setVisible(true);
。