بسم الله الرحمن الرحيم ...
طبعا أكيد كثير منكم يضيف كومبوننت إلى إطارات JFrame بإستخدام الأمر
JFrame.getContentPane().add(someComponentName)
لكن المشكلة قد تواجهك .. كيف تضيف صورة أو شكل هندسي Shape ??
الحل :
1- إنشاء كلاس من نوع جديد لنسميه MyNewComponent والذي سيشتق من Component أو JComponent.
2- الخطوة الثانية .. كتابة الباينت ميثود بحيث ترسم ما تريده في الشكل المعني ...
public void paint(Graphics g){
//....some code to draw an image in a component3- يمكنك إضافة ميثود لتحديد حجم الكمبوننت.
4- أو حتى كونستركتور يرسل للكلاس اسم الصورة التي تريد جعلها كمبوننت
=========
كيف يمكنك عمل UNDO ؟؟؟
أفضل شيء هو استخدام Stack. أي كانت عملية التراجع التي تريدها فلو كانت تراجع عن رسم شكل إضافة شكل أو إذا كانت في Text Editor المهم ..
عموما الكلام في هالموضوع معقد شوي (للمبتدئين على الأقل) لذلك سأورد مثال وأنتظر أي أسئلة في خصوصه.
هذا المثال عبارة عن برنامج تختار فيه الشكل من comboBox وتختار رسمه ليضاف إلى الإطار (حسب الطريقة المذكورة أعلاه) كذلك إمكانية التراجع عن ذلك بزر UNDO
أرجو تجربته ------> والأهم إنتقاده.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
public class ShapeDrawing extends JFrame implements ActionListener{
/*
The Color Chooser
*/
JColorChooser jcc = new JColorChooser(Color.blue);
/*
This defines a stack, which will be populated by the shapes.
It will be used when we make the undo command
*/
ShapesDrawnStack sds = new ShapesDrawnStack();
/*
The three control buttons
*/
JButton but = new JButton("Choose Color");
JButton drawShape = new JButton("Draw the Shape");
JButton undo = new JButton("Undo");
/*
An array contining the names of the possible shapes
This array is passed as a parameter for the JComboBox compnenet
*/
String [] shapes = {"Rectangle","Ellipse","Line"};
JComboBox jcb = new JComboBox(shapes);
/*
This returns the main container for the application.
We will add Components to it ---> equivalent to JFrame.getContentPane();
*/
Container cp = getContentPane();
/*
Defining a dummy variable of color.
This represents the current color for the shape to be drawn
*/
Color currentColor = new Color(0);
/*
the up panel is the one that have the button
the down is the one to which we draw
*/
JPanel up = new JPanel();
JPanel down = new JPanel();
/*
If checked the shape will be filled
*/
JCheckBox fill = new JCheckBox("Fill Shape");
/*
this boolean value tracks the status of the JCheckBox.
*/
boolean fillShape = false ;
public ShapeDrawing()
{
cp.setLayout(new BorderLayout());
cp.add(up,BorderLayout.NORTH);
up.setLayout(new FlowLayout());
up.add(jcb);
up.add(but);
up.add(fill);
up.add(drawShape);
cp.add(undo,BorderLayout.SOUTH);
cp.add(down,BorderLayout.CENTER);
down.setLayout(null);
down.setSize(500,500);
fill.addActionListener(this);
but.addActionListener(this);
drawShape.addActionListener(this);
undo.addActionListener(this);
setSize(600,600);
show();
}
public void actionPerformed(ActionEvent ae)
{
if(ae.getSource() == but) // when you press the Choose Color Button
{
Color check = jcc.showDialog(null,"Chooser a Color",Color.black);
if(check==null)
{
return;
// don't do anything , keep the current color as it is.
}
else
{
currentColor = check ;
// sets the new color
}
}
else
if(ae.getSource()==fill) // when you click the fill checkbox
{
fillShape = !fillShape; // change with the status of the JCheckBox
}
else
if(ae.getSource()==drawShape) // when u choose to draw a shape
{
String x = jcb.getSelectedItem().toString(); // gets the Item to be drawn
if(x.equals("Ellipse"))
{
Random rnd = new Random();
int hi = rnd.nextInt(500);
int wi = rnd.nextInt(500);
int hi2 = rnd.nextInt(500);
int wi2 = rnd.nextInt(500);
/* refer to ShapeContainer */
JComponent zz = new ShapeContainer("Ellipse",0,0,hi,wi,currentColor,fillShape);
down.add(zz);
zz.setBounds(hi2,wi2,hi,wi); // sets the bounds
sds.pushShape(zz); // pushes the Component to a stack
}
else if(x.equals("Rectangle"))
{
Random rnd = new Random();
int hi = rnd.nextInt(500);
int wi = rnd.nextInt(500);
int hi2 = rnd.nextInt(500);
int wi2 = rnd.nextInt(500);
JComponent zz = new ShapeContainer("Rectangle",0,0,hi,wi,currentColor,fillShape);
down.add(zz);
zz.setBounds(hi2,wi2,hi,wi);
sds.pushShape(zz);
}
else if(x.equals("Line"))
{
Random rnd = new Random();
int hi = rnd.nextInt(500);
int wi = rnd.nextInt(500);
int hi2 = rnd.nextInt(500);
int wi2 = rnd.nextInt(500);
JComponent zz = new ShapeContainer("Line",0,0,hi,wi,currentColor,fillShape);
down.add(zz);
zz.setBounds(hi2,wi2,hi,wi);
sds.pushShape(zz);
}
}
else
if(ae.getSource()==undo)
{
JComponent aaa = (JComponent)sds.pop(); // pops the top stack member
if(aaa!=null)
aaa.setVisible(false); // hide the component (delete it)
else
JOptionPane.showMessageDialog(null,"There are no more drawn shapes on the screen", "Can't undo",JOptionPane.ERROR_MESSAGE);
return; // nothing to be undo !!
}
}
public static void main(String [] args)
{
new ShapeDrawing();
}
}
class ShapesDrawnStack {
Stack st ;
public ShapesDrawnStack()
{
st = new Stack();
}
public void pushShape(JComponent s)
{
st.push(s);
}
public Object pop()
{
if(!st.isEmpty())
return st.pop();
else
return null;
}
}
class ShapeContainer extends JComponent {
String type;
int x,y,w,h;
Color c;
boolean fill;
public ShapeContainer(String type , int x , int y , int w , int h , Color c,boolean fill)
{
this.type = type ;
this.x = x ;
this.y = y ;
this.w = w ;
this.h = h ;
this.c = c ;
this.fill=fill;
}
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.setColor©;
if(type.equals("Ellipse"))
{
Ellipse2D.Float el = new Ellipse2D.Float(x,y,w,h);
if(fill)
g2.fill(el);
else
g2.draw(el);
}
else
if(type.equals("Rectangle"))
{
Rectangle el = new Rectangle(x,y,w,h);
if(fill)
g2.fill(el);
else
g2.draw(el);
}
else
if(type.equals("Line"))
{
Line2D.Float el = new Line2D.Float(x,y,w,h);
g2.draw(el);
}
}
}