Frage

I' making this simple paintbrush-type paint toolbox (some interesting ideas in my previous question)

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class MainClass2{
    static JLabel colorlabel = new JLabel(" Color ");
    public static JLabel xlab = new JLabel("0");
    public static JLabel ylab = new JLabel("0");

    static JFrame frame1 = new JFrame();
    static JButton quitbutton = new JButton("Quit");
    static JButton infobutton = new JButton("Info");
    static JButton clearbutton = new JButton("Clear");
    static JButton savebutton = new JButton("Save");
    private static int stroke1 = 4;
    static SpinnerNumberModel spinnervals = new SpinnerNumberModel(stroke1,1,15,1);

    static JSpinner spinnerbrush = new JSpinner(spinnervals);

    static JButton selectcolor = new JButton("Select Color");
    static JButton selectbg = new JButton("Select Background");
    public static Color col1 = Color.WHITE;
    private static Color col2 = Color.WHITE;

    static AuxClass4 panel1 = new AuxClass4(col1, col2, stroke1); 

    static JPanel panel2 = new JPanel();
    static JPanel panel3 = new JPanel();
    static JPanel panel4 = new JPanel();

    private static void addPanel1(){

        panel1.setPreferredSize(new Dimension(800,500));
    }
    private static void addPanel2(){
        ButtonAction inst1 = new ButtonAction();
        xlab.setMinimumSize(new Dimension(30,30));
        ylab.setMinimumSize(new Dimension(30,30));
        xlab.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        ylab.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        panel2.add(new JLabel(" X: "));
        panel2.add(xlab);
        panel2.add(new JLabel(" Y: "));
        panel2.add(ylab);

        panel2.add(savebutton);
        panel2.add(clearbutton);
        panel2.add(quitbutton);
        panel2.add(infobutton);
        panel2.setLayout(new FlowLayout());

        quitbutton.addActionListener(inst1);
        infobutton.addActionListener(inst1);
        clearbutton.addActionListener(inst1);
        savebutton.addActionListener(inst1);

        selectcolor.addActionListener(inst1);
        selectbg.addActionListener(inst1);
    }
    //add to panel3
    private static void addPanel3(){
        StrokeAction inst2 = new StrokeAction();
        spinnerbrush.addChangeListener(inst2);
        panel3.add(new JLabel("Stroke size"));
        panel3.add(spinnerbrush);
        panel3.add(selectcolor);
        panel3.add(new JLabel("Current color:"));
        colorlabel.setSize(20, 20);
        colorlabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        colorlabel.setOpaque(true);
        colorlabel.setBackground(Color.WHITE);
        colorlabel.setForeground(Color.WHITE);
        panel3.add(colorlabel);
        panel3.add(selectbg);

    }

    private static class ButtonAction implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent arg0) {
            if (arg0.getSource()==quitbutton){
                System.exit(0);
            }
            else if(arg0.getSource()==infobutton){
                JOptionPane.showMessageDialog(frame1, "Paint Toolbox designed in Java");
            }
            else if(arg0.getSource()==selectcolor){

                panel1.changeColor();

            }
            else if(arg0.getSource()==selectbg){
                panel1.changeBg();
            }
            else if(arg0.getSource()==clearbutton){
                panel1.colfg = panel1.colbg;
                colorlabel.setBackground(panel1.colfg);
                colorlabel.setForeground(panel1.colfg);
                panel1.setForeground(null);

            }
            else if(arg0.getSource()==savebutton){
                panel1.saveImage();
            }

        }

    }

    private static class StrokeAction implements ChangeListener{

        @Override
        public void stateChanged(ChangeEvent arg0) {
            if (arg0.getSource()==spinnerbrush){
                Object o1 = spinnervals.getValue();
                Integer int1 = (Integer) o1;
                stroke1 = int1.intValue();
                panel1.changeStroke(stroke1);
            }

            // TODO Auto-generated method stub      
        }

    }

    public static void main(String args[]){

        addPanel1();
        addPanel2();
        addPanel3();
        frame1.add(panel1, BorderLayout.NORTH);
        frame1.add(panel2, BorderLayout.SOUTH);
        frame1.add(panel3, BorderLayout.CENTER);
        frame1.setTitle("PaintBox v2.2");
        frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame1.setSize(800,600);
        frame1.setResizable(false);
        frame1.setLocationRelativeTo(null);
        frame1.setVisible(true);

    }

}

class AuxClass4 extends JPanel implements MouseMotionListener{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private int xval;
    private int yval;
    public Color colfg;
    public Color colbg;
    public int strokesize;
    public int fileorder;


    public AuxClass4(Color input1, Color input2, int input3){
        colfg=input1;
        colbg=input2;
        strokesize = input3;
        this.setBorder(BorderFactory.createLineBorder(Color.CYAN, 10));
        this.setBackground(colbg);
        //this.setMaximumSize(new Dimension(500,380));
        this.addMouseMotionListener(this);

    }

    public void paintComponent(Graphics g1){
        super.paintComponent(g1);
        g1.setColor(colfg);
        g1.fillRect(xval, yval, strokesize, strokesize);

    }

    @Override
    public void mouseDragged(MouseEvent arg0) {
        xval = arg0.getX();
        yval = arg0.getY();
        repaint(xval, yval, strokesize,strokesize);

        // TODO Auto-generated method stub

    }

    @Override
    public void mouseMoved(MouseEvent arg0) {
        xval = arg0.getX();
        yval = arg0.getY();
        String xvalret = Integer.toString(xval);
        String yvalret = Integer.toString(yval);
        MainClass2.xlab.setText(" " + xvalret + " ");
        MainClass2.ylab.setText(" " + yvalret + " ");

    }
    public void changeColor(){
        colfg = JColorChooser.showDialog(this, "Select color", colfg);
        MainClass2.colorlabel.setBackground(colfg);
        MainClass2.colorlabel.setForeground(colfg); 
    }

    public void changeBg(){
        colbg=JColorChooser.showDialog(this, "Select color", Color.WHITE);
        colfg=colbg;
        this.setBackground(colbg);
        MainClass1.colorlabel.setBackground(colfg); 
        MainClass1.colorlabel.setForeground(colfg); 


    }

    public void changeStroke(int inputstroke){
        strokesize=inputstroke;
    }

    public void saveImage(){
        final String dir = System.getProperty("user.dir");
        JOptionPane.showMessageDialog(this, "File saved under " + dir + "/saveimage" + fileorder +".png");
        fileorder+=1;

    }

}

It works fine for now, but I started wondering if it is possible to implement undo and redo methods for Graphics objects. Intuitively, there should be some way to add the created objects to some table in a 'historical' order. User then should be able to navigate in this table.

Unfortunately, I have no experience with this approach, especially with graphics, so any suggestion would be massively welcome.

War es hilfreich?

Andere Tipps

Take a look at the command pattern. I think this javaworld article explains it quite nicely.

In a nutshell you will have to have an interface containing undo and redo. Objects that implement this will be added to a list. As you undo and redo you can navigate through the list calling undo and redo. It means that you may have to write more code becuase for every event you actually draw you will have to write the equivelent to undo it.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top