[英]Drawing multiple connected lines in JApplet by using paintComponent
我試圖創建用戶可以在Canvas中畫線的應用程序。 用戶可以從下拉列表中選擇方向,然后輸入行長。 第一行從Canvas的中心開始,下一條從上一條的結束處開始,依此類推-用戶可以一條一條繪制多條線,並且所有線都已連接。
我有兩個類-TurtleApplet,它使用程序邏輯創建GUI和Canvas:
public class TurtleApplet extends JApplet implements ActionListener
{
private JComboBox direction;
private JRadioButton activeButton, passiveButton;
private Button drawButton;
private ButtonGroup group;
private TextField pixels;
private Canvas canvas;
private JPanel panel;
private JPanel panelRadio;
private Button quitPr;
public void init()
{
//directions
String[] directionStrings = { "Right", "Left", "Up", "Down"};
direction = new JComboBox(directionStrings);
//direction.setSelectedIndex(4);
//Buttons
activeButton = new JRadioButton("Aktīvs");
passiveButton = new JRadioButton("Neaktīvs");
quitPr = new Button("Iziet");
//Canvas
canvas = new Canvas();
//canvas.setSize(600, 500);
//canvas.setBackground(Color.red);
canvas.setBorder(BorderFactory.createTitledBorder("Turtle drawing"));
//Panels
panel = new JPanel();
panelRadio =new JPanel();
panel.setLayout(new FlowLayout());
panelRadio.setLayout(new FlowLayout());
//actionListener
activeButton.addActionListener(this);
passiveButton.addActionListener(this);
activeButton.setSelected(true);
quitPr.addActionListener(this);
//Add radiobuttons
group = new ButtonGroup();
group.add(activeButton);
group.add(passiveButton);
//Add Buttons to panel
panelRadio.add(activeButton);
panelRadio.add(passiveButton);
//textfield
pixels = new TextField(12);
//Draw button
drawButton = new Button("Zīmēt");
drawButton.addActionListener(this);
direction.addActionListener(this);
panel.add(panelRadio);
panel.add(pixels);
panel.add(direction);
panel.add(drawButton);
panel.add(quitPr);
getContentPane().add(panel,"North");
getContentPane().add(canvas, "Center");
setSize(650,550);
}
public void actionPerformed( ActionEvent e)
{
if ( e.getSource() == activeButton ) {
drawButton.setVisible(true);
pixels.setEditable(true);
} else if (e.getSource() == passiveButton) {
drawButton.setVisible(false);
pixels.setEditable(false);
} else if(e.getSource() == quitPr){
System.exit(0);
}else if(e.getSource() == drawButton){
int y = Integer.parseInt(pixels.getText());
canvas.addPatt(direction.getSelectedIndex(), Integer.parseInt(pixels.getText()));
repaint();
}
//repaint();
}
}
public class Canvas extends JPanel {
private static final int RIGHT=0, LEFT=1, UP=2, DOWN=3;
public static final int WIDTH=600, HEIGHT=500;
private int direction = 0 ;
private int pixels;
//rivate List points;
public Polygon t = new Polygon();
//public Dimension d = getSize();
public int x = WIDTH/2;
public int y = HEIGHT/2;
public Canvas() {
setSize(WIDTH, HEIGHT);
}
public void addPatt(int pat, int lev) {
direction = pat;
pixels = lev;
}
public void paintComponent(Graphics g) {
switch (direction) {
case LEFT:
drawLineLeft(g, pixels);
break;
case RIGHT:
drawLineRight(g, pixels);
break;
case UP:
drawLineUp(g, pixels);
break;
case DOWN:
drawLineDown(g, pixels);
break;
}
}
private void drawLineLeft(Graphics g, int pix){
if(pix > 0){
g.drawLine(x, y, x-10*pix, y);//left
x =x -10*pix;
}
}
private void drawLineUp(Graphics g, int pix){
if(pix > 0){
g.drawLine(x, y, x, y-10*pix);//up
y = y-10*pix;
}
}
private void drawLineRight(Graphics g, int pix){
if(pix > 0){
g.drawLine(x, y, x+10*pix, y);//right
x = x+10*pix;
}
}
private void drawLineDown(Graphics g, int pix){
if(pix > 0){
g.drawLine(x, y, x, y+10*pix);// down
y = y+10*pix;
}
}
}
Applet有效,但是問題是在繪制新行時保存以前的行。 當用戶輸入行的方向和長度並按下按鈕時,新的行會出現在屏幕上,但是前一行會消失。 我知道問題出在paintComponent方法上,但是我不知道如何准確地糾正我的代碼以使所有行都可見。 建議我將點坐標存儲在數組中,然后通過遍歷paintComponent中的數組來繪制線,但是我不知道該如何實現。 也許有更好的解決方案?
就像我在上一個問題中所說的那樣, case
狀態就像if-else
,您只允許它畫一條線。 您需要維護一個“行” List
,每次調用paintComponent
方法時都可以對其進行迭代
因為一行由多個屬性表示,所以最好將這些信息封裝到一個簡單的類或POJO中
public enum Direction {
UP, DOWN, LEFT, RIGHT
}
public class Line {
private Direction direction;
private int length;
public Line(Direction direction, int length) {
this.direction = direction;
this.length = length;
}
public Direction getDirection() {
return direction;
}
public int getLength() {
return length;
}
}
在這里,我將direction屬性分為一個簡單的enum
,這使您可以在程序中的其他位置更輕松地引用這些屬性
然后,維護一個Line
的List
,當調用paintComponent
時,您只需重新迭代並重新繪制即可。
public class Canvas extends JPanel {
public static final int WIDTH = 600, HEIGHT = 500;
public int x = WIDTH / 2;
public int y = HEIGHT / 2;
private List<Line> lines;
public Canvas() {
lines = new ArrayList<>(25);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(WIDTH, HEIGHT);
}
public void addPatt(Direction direction, int length) {
lines.add(new Line(direction, length));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
switch (line.getDirection()) {
case UP:
drawLineUp(g, line.getLength());
break;
case DOWN:
drawLineDown(g, line.getLength());
break;
case LEFT:
drawLineLeft(g, line.getLength());
break;
case RIGHT:
drawLineDown(g, line.getLength());
break;
}
}
}
private void drawLineLeft(Graphics g, int pix) {
if (pix > 0) {
g.drawLine(x, y, x - 10 * pix, y);//left
x = x - 10 * pix;
}
}
private void drawLineUp(Graphics g, int pix) {
if (pix > 0) {
g.drawLine(x, y, x, y - 10 * pix);//up
y = y - 10 * pix;
}
}
private void drawLineRight(Graphics g, int pix) {
if (pix > 0) {
g.drawLine(x, y, x + 10 * pix, y);//right
x = x + 10 * pix;
}
}
private void drawLineDown(Graphics g, int pix) {
if (pix > 0) {
g.drawLine(x, y, x, y + 10 * pix);// down
y = y + 10 * pix;
}
}
}
記住,Swing中的繪制是破壞性的,每次調用paintComponent
時, paintComponent
重新繪制組件的整個狀態。
有關繪畫工作原理的更多詳細信息,請參見“ AWT中的繪畫”和“搖擺和執行自定義繪畫 ”
建議我將點坐標存儲在數組中,然后通過遍歷paintComponent中的數組來繪制線,但是我不知道該如何實現。
這取決於您的確切要求。
如果您需要添加/刪除行的功能,那么這可能是最好的方法。
如果只需要添加線的功能,則可能需要將線直接繪制到BufferedImage上,然后在JLabel上將BufferedImage顯示為圖標。
查看“ 自定義繪畫方法” ,它比較了兩種方法並提供了這兩種方法的工作示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.