Images do not appear in applet - java

I am working on a game.I want to add images to the applet but they do not appear there until I resize or minimize the applet.I do not know whether my image observer is wrong or not.
The images are in right path.Their in build and class folder with correct spelling. What is wrong with my code?
any help would be much appreciated.
public class game extends JApplet implements KeyListener, Runnable {
ScreenDir sd;
Image ball;
Image flower;
public void init() {
sd = new ScreenDir(this);
ball = getImage(getCodeBase(), "ball.jpg");
ballb = new Ball(50, 50, 30, 40, Color.red, ball, sd);
sd.add(ball);
flower = getImage(getCodeBase(), "flower.gif");
//class Flower is just defined like class Ball
flowerf = new Flower(60, 100, 30, 30, Color.green, flower, sd);
sd.add(flower);
}
public void paint(Graphics g) {
sd.draw(g);
}
//These are for moving the ball
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(15);
} catch (InterruptedException ex) {}}}
public class ScreenDir {
ArrayList<Object> olist;
JApplet parent;
public ScreenDir(JApplet parent) {
this.parent = parent;
olist = new ArrayList<>();
}
public void add(Object o) {
olist.add(o);
}
Image Img;
Graphics oG;
Img = parent.createImage(parent.getWidth(), parent.getHeight());
oG = offImg.getGraphics();
for(int i = 0;i<olist.size ();i++){
olist.get(i).draw(offG);
}
g.drawImage (Img,0, 0, parent);
}
public class Ball extends Object {
ScreenDir sd;
public ball(int x, int y, int w, int h, Color c, Image pi, ScreenDir sd) {
{
this.sd = sd;
}
public void draw(Graphics g) {
g.drawImage(pi, x, y, w, h, null);
}
public abstract class Object {
int x, y, w, h;
Color c;
Image pi;
public Object(int x, int y, int w, int h, Color c, Image pi) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.c = c;
this.pi = pi;
}
public abstract void draw(Graphics g) {
}

Applets load images asynchronously, so it is likely the images are not fully loaded before the applet goes to paint. But every Java component worth mentioning implements an ImageObserver that means it will get updates on image loading. So to fix the problem, change this:
g.drawImage(pi, x, y, w, h, null);
To this:
g.drawImage(pi, x, y, w, h, this);
Update
I mistakenly thought the drawImage method was part of the JApplet (which is an ImageObserver). You might simply change the method declaration & painting line to:
public void draw(Graphics g, ImageObserver io) {
g.drawImage(pi, x, y, w, h, io);
}
Then to call it, change:
sd.draw(g);
To:
sd.draw(g, this);

Related

Strange behavior when I move a JComponent in a JPanel

I am in the process of implementing a simple graph editor. It should be possible to create any Node (Sphere object) by mouse click and move it by drag and move. It works as far as it goes, but it behaves very strangely. When I click on the node, it slides away from the cursor. The hitbox from every Sphere object is strange too, but I can't explain why. Is there a better solution for my code?
This behavior
public class EditorPanelView extends Panel
{
private static EditorPanelView instance = null;
private static GraphController graphController = GraphController.getInstance();
private EditorPanelView(Color color, int x, int y, int width, int height) {
super(new BorderLayout(), color, x, y, width, height);
addMouseAdapter();
}
private void addMouseAdapter() {
MouseAdapter mouseAdapter = new MouseAdapter() {
private Sphere sphere;
#Override
public void mousePressed(MouseEvent e) {
if (getComponentAt(e.getX(), e.getY()) instanceof Sphere) {
sphere = (Sphere) getComponentAt(e.getPoint());
}
}
#Override
public void mouseClicked(MouseEvent e) {
Sphere sphere = new Sphere(e.getX(), e.getY());
add(sphere);
System.out.println("MOUSE CLICKED ON EDITORPANEL; SPHERE CREATED!");
revalidate();
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
Point p2 = e.getPoint();
Point loc = sphere.getLocation();
loc.translate(p2.x - sphere.getX(), p2.y - sphere.getY());
sphere.setLocation(loc);
}
#Override
public void mouseReleased(MouseEvent e) {
sphere = null;
System.out.println("Mouse released!");
}
};
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
}
public static EditorPanelView getInstance(Color color, int x, int y, int width, int height) {
return Objects.requireNonNullElseGet(instance, () -> new EditorPanelView(color, x, y, width, height));
}
}
public class Sphere extends JComponent{
private int positionX;
private int positionY;
private final int width = 50;
private final int height = 50;
public Sphere(int x, int y) {
this.positionX = x;
this.positionY = y;
}
#Override
public void paintComponent(Graphics graphics) {
Graphics2D sphere = (Graphics2D) graphics;
sphere.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
sphere.setPaint(Color.BLACK);
sphere.fillOval(positionX -(width/2), positionY -(height/2), width, height);
}
}
public class FrameView extends JFrame {
private static FrameView instance = null;
private static final Color FRAMECOLOR = Color.darkGray;
private FrameView() {
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
GraphController graphController = GraphController.getInstance();
getContentPane().setBackground(FRAMECOLOR);
setTitle("Graph Editor");
setSize((int) size.getWidth()-200, (int) size.getHeight()-200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
getContentPane().setLayout(new GroupLayout(getContentPane()));
setJMenuBar(MenuBarView.getInstance());
add(EditorPanelView.getInstance(Color.LIGHT_GRAY, 260, 53, getWidth()-270, getHeight()-113));
add(OverviewPanelView.getInstance(Color.gray, 10, 53, 240, getHeight()-113));
add(ButtonPanelView.getInstance(FRAMECOLOR, 5, 5, getWidth()-10, 42));
}
public static JFrame getInstance() {
return Objects.requireNonNullElseGet(instance, FrameView::new);
}
}
public class Panel extends JPanel {
LayoutManager layout;
public Panel(LayoutManager layout, Color color, int x, int y, int width, int height) {
this.layout = layout;
setLayout(this.layout);
setBounds(x, y, width, height);
setBackground(color);
}
}
I tried to change the x and y coordinates in EditorPanelView::addMouseAdapter()

Java 9 replacement for SwingUtilities3.setDelegateRepaintManager

While trying to port swing code to be compliant with the Java module system I got stuck trying to replace SwingUtilities3.setDelegateRepaintManager.
I have a component, which when any of its children requests a repaint then I need to transform the region (in particular this is trying to port the code of org.pbjar.jxlayer.plaf.ext.TransformUI for anyone who knows of this). Currently this is done by setting the delegate repaint manager of the component and intercepting the calls to addDirtyRegion.
Now with Java 9 the method to do so isn't available anymore as public api. The original code provided an alternative method which was originally used for older versions of Java where SwingUtilities3.setDelegateRepaintManagerwasn't available, which simply replaced the global RepaintManager with a delegating implementation. It checks each call if the component is contained in the actual component which needs the transformation. This solution however throws away all internal data of the RepaintManager and results in heavy flickering while the frame is resized.
Here an abridged version of the code currently used:
SwingUtilities3.setDelegateRepaintManager(component, new TransformRepaintManger());
...
class TransformRepaintManager extends RepaintManager {
#Override
public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
if (c.isShowing()) {
Point point = c.getLocationOnScreen();
SwingUtilities.convertPointFromScreen(point, c);
Rectangle transformPortRegion = transform(new Rectangle(x + point.x, y + point.y, w, h), c);
RepaintManager.currentManager(c)
.addDirtyRegion(c,
transformPortRegion.x, transformPortRegion.y,
transformPortRegion.width, transformPortRegion.height);
}
}
}
and the alternative approach which causes flickering (DelegateRepaintManager simply takes the original RepaintManager and forwards all calls to it):
class TransformRPMFallBack extends DelegateRepaintManager {
#Override
public void addDirtyRegion(JComponent aComponent,int x, int y, int w, int h) {
if (aComponent.isShowing()) {
JComponent targetParent = findTargetParent(aComponent);
if (targetParent != null) {
Point point = aComponent.getLocationOnScreen();
SwingUtilities.convertPointFromScreen(point, targetParent);
Rectangle transformPortRegion = transform(new Rectangle(x + point.x, y + point.y, w, h));
addDirtyRegion(targetParent,
transformPortRegion.x, transformPortRegion.y,
transformPortRegion.width, transformPortRegion.height);
return;
}
}
super.addDirtyRegion(aComponent, x, y, w, h);
}
}
I know one option would be to simply add --add-exports java.desktop/com.sun.java.swing=<module name> to the startup parameters, but as this is intended for a library forcing everyone using it to do so isn't the best option in my opinion.
Update:
Here is an example which demonstrates the two approaches above.
It consists of a panel which is rotated 90 degree in the JLayer. Toggling the checkboxes paints the left (visually top) or right (visually bottom) part of the component in a different color. The different approaches can be changed by setting the static vairable in TransformLayerUI. One can observe the following behaviours:
SolutionApproach.FLICKERING: Clicking the checkboxes behaves as expected. Resizing the window results in flickering (for such a small example it isn't very bas but for larger applications it gets much worse)
SolutionApproach.ILLEGAL: Same as SolutionApproach.FLICKERING but without the flickering.
SolutionApproach.NONE: Clicking the checkboxes only repaints a quarter of the area that should change. This is the problem that needs to be solved. If the TestPanel (or any possible children) requests a repaint the correct area of the JLayer should be repainted.
public class TransformTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Transform Test");
JPanel contentPanel = new JPanel(new BorderLayout());
TestPanel testPanel = new TestPanel();
JLayer<TestPanel> testLayer = new JLayer<>(testPanel, new TransformLayerUI());
contentPanel.add(testLayer);
frame.getContentPane().add(contentPanel, BorderLayout.CENTER);
JCheckBox leftCheck = new JCheckBox("Left active");
leftCheck.addActionListener(e -> testPanel.setLeftActive(leftCheck.isSelected()));
JCheckBox rightCheck = new JCheckBox("Right active");
rightCheck.addActionListener(e -> testPanel.setRightActive(rightCheck.isSelected()));
JComponent buttonPanel = Box.createHorizontalBox();
buttonPanel.add(leftCheck);
buttonPanel.add(rightCheck);
frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
#SuppressWarnings("unchecked")
static class TransformLayerUI extends LayerUI<TestPanel> {
enum SolutionApproach {
ILLEGAL,
FLICKERING,
NONE
}
static SolutionApproach approach = SolutionApproach.ILLEGAL;
#Override
public void installUI(JComponent c) {
super.installUI(c);
switch (approach) {
case ILLEGAL:
SwingUtilities3.setDelegateRepaintManager(((JLayer<? extends JComponent>) c).getView(),
new TransformRepaintManager());
break;
case FLICKERING:
if (!(RepaintManager.currentManager(c) instanceof FallbackTransformRepaintManger)) {
RepaintManager.setCurrentManager(
new FallbackTransformRepaintManger(RepaintManager.currentManager(c)));
}
break;
case NONE:
break;
}
}
private AffineTransform calcTransform(Dimension size) {
AffineTransform at = new AffineTransform();
Point2D center = new Point2D.Double(size.getWidth() / 2f, size.getHeight() / 2f);
at.translate(center.getX(), center.getY());
at.quadrantRotate(1);
at.translate(-center.getX(), -center.getY());
return at;
}
private Rectangle transform(Dimension size, final Rectangle rect) {
Area area = new Area(rect);
area.transform(calcTransform(size));
return area.getBounds();
}
#Override
public void paint(Graphics g, JComponent c) {
((Graphics2D) g).transform(calcTransform(c.getSize()));
super.paint(g, c);
}
#Override
public void doLayout(JLayer<? extends TestPanel> l) {
l.getView().setBounds(transform(l.getSize(), new Rectangle(l.getSize())));
}
#Override
public Dimension getPreferredSize(JComponent c) {
return transform(((JLayer<? extends JComponent>) c).getView().getPreferredSize());
}
#Override
public Dimension getMaximumSize(JComponent c) {
return transform(((JLayer<? extends JComponent>) c).getView().getMaximumSize());
}
#Override
public Dimension getMinimumSize(JComponent c) {
return transform(((JLayer<? extends JComponent>) c).getView().getMinimumSize());
}
private Dimension transform(final Dimension size) {
Area area = new Area(new Rectangle2D.Double(0, 0, size.getWidth(), size.getHeight()));
area.transform(calcTransform(size));
Rectangle2D bounds = area.getBounds2D();
size.setSize(bounds.getWidth(), bounds.getHeight());
return size;
}
class TransformRepaintManager extends RepaintManager {
#Override
public void addInvalidComponent(JComponent invalidComponent) {
Container layer = SwingUtilities.getAncestorOfClass(JLayer.class, invalidComponent);
RepaintManager.currentManager(layer).addInvalidComponent((JComponent) layer);
}
#Override
public void addDirtyRegion(JComponent comp, int x, int y, int w, int h) {
if (comp.isShowing()) {
Container layer = SwingUtilities.getAncestorOfClass(JLayer.class, comp);
dispatchRepaint(comp, layer, TransformLayerUI.this, new Rectangle(x, y, w, h));
}
}
}
static void dispatchRepaint(Component comp, Component layer, TransformLayerUI ui, Rectangle rect) {
Point point = comp.getLocationOnScreen();
SwingUtilities.convertPointFromScreen(point, layer);
Rectangle transformPortRegion =
ui.transform(layer.getSize(),
new Rectangle(rect.x + point.x, rect.y + point.y, rect.width, rect.height));
RepaintManager.currentManager(layer).addDirtyRegion((JComponent) layer,
transformPortRegion.x, transformPortRegion.y,
transformPortRegion.width, transformPortRegion.height);
}
static class FallbackTransformRepaintManger extends DelegateRepaintManager {
FallbackTransformRepaintManger(RepaintManager delegate) {
super(delegate);
}
#Override
public void addDirtyRegion(JComponent aComponent, int x, int y, int w, int h) {
if (aComponent.isShowing()) {
JLayer<?> layer = (JLayer<?>) SwingUtilities.getAncestorOfClass(JLayer.class, aComponent);
if (layer != null) {
LayerUI<?> layerUI = layer.getUI();
if (layerUI instanceof TransformLayerUI) {
TransformLayerUI ui = (TransformLayerUI) layerUI;
dispatchRepaint(aComponent, layer, ui, new Rectangle(x, y, w, h));
return;
}
}
}
super.addDirtyRegion(aComponent, x, y, w, h);
}
}
static class DelegateRepaintManager extends RepaintManager {
private final RepaintManager delegate;
DelegateRepaintManager(RepaintManager delegate) {
this.delegate = delegate;
}
#Override
public void addInvalidComponent(JComponent invalidComponent) {
delegate.addInvalidComponent(invalidComponent);
}
#Override
public void removeInvalidComponent(JComponent component) {
delegate.removeInvalidComponent(component);
}
#Override
public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
delegate.addDirtyRegion(c, x, y, w, h);
}
#Override
public void addDirtyRegion(Window window, int x, int y, int w, int h) {
delegate.addDirtyRegion(window, x, y, w, h);
}
#Override
#Deprecated
public void addDirtyRegion(Applet applet, int x, int y, int w, int h) {
delegate.addDirtyRegion(applet, x, y, w, h);
}
#Override
public Rectangle getDirtyRegion(final JComponent c) {
return delegate.getDirtyRegion(c);
}
#Override
public void markCompletelyDirty(final JComponent c) {
delegate.markCompletelyDirty(c);
}
#Override
public boolean isCompletelyDirty(final JComponent c) {
return delegate.isCompletelyDirty(c);
}
#Override
public Dimension getDoubleBufferMaximumSize() {
return delegate.getDoubleBufferMaximumSize();
}
#Override
public void markCompletelyClean(final JComponent c) {
delegate.markCompletelyClean(c);
}
public RepaintManager getDelegateManager() {
return delegate;
}
#Override
public void setDoubleBufferMaximumSize(final Dimension d) {
delegate.setDoubleBufferMaximumSize(d);
}
#Override
public void validateInvalidComponents() {
delegate.validateInvalidComponents();
}
#Override
public void paintDirtyRegions() {
delegate.paintDirtyRegions();
}
#Override
public Image getOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) {
return delegate.getOffscreenBuffer(c, proposedWidth, proposedHeight);
}
#Override
public Image getVolatileOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) {
return delegate.getVolatileOffscreenBuffer(c, proposedWidth, proposedHeight);
}
#Override
public boolean isDoubleBufferingEnabled() {
return delegate.isDoubleBufferingEnabled();
}
#Override
public void setDoubleBufferingEnabled(final boolean flag) {
delegate.setDoubleBufferingEnabled(flag);
}
}
}
static class TestPanel extends JPanel {
private boolean leftActive;
private boolean rightActive;
TestPanel() {
setPreferredSize(new Dimension(600, 300));
setMinimumSize(new Dimension(600, 300));
setMaximumSize(new Dimension(600, 300));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (leftActive) {
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth() / 2, getHeight());
}
if (rightActive) {
g.setColor(Color.GREEN);
g.fillRect(getWidth() / 2, 0, getWidth() / 2, getHeight());
}
g.setColor(Color.BLACK);
g.drawString("Left", (getWidth() - 50) / 4, getHeight() / 2 + 10);
g.drawString("Right", getWidth() / 2 + (getWidth() - 50) / 4, getHeight() / 2 + 10);
}
public void setLeftActive(boolean leftActive) {
this.leftActive = leftActive;
repaint(0, 0, getWidth() / 2, getHeight());
}
public void setRightActive(boolean rightActive) {
this.rightActive = rightActive;
repaint(getWidth() / 2, 0, getWidth() / 2, getHeight());
}
}
}
Update 2:
Having FallbackTransformRepaintManger extend RepaintManager instead of DelegateRepaintManager. However this would make using the component a destructive operation as any other custom RepaintManager set previously would be overwritten.

java graphics - cannot save shapes drawn

I have a java application that i have been coding, it is an application that can allow me to draw shapes like a rectangle. My application can draw shapes but I cannot save them because when i try to draw a new shape and I click somewhere else the previously drawn shape disappears and is replaced by a new one. I tried array list to save my shapes but it does not work.
here is my code:
public class Toile extends JPanel {
Vector<Forme> forme = new Vector<Forme>();
private Color couleur;
private int x;
private int y;
private int x2;
private int y2;
private Oval oval;
private Rectangl rect;
public Toile(){
initComponents();
}
public void initComponents(){
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
formMousePressed(evt); }
public void mouseReleased(java.awt.event.MouseEvent evt) {
formMouseReleased(evt); } });
addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
formMouseDragged(evt); } });
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(couleur);
drawfillRect(g, x, y, x2, y2);
}
public void setStartPoint(int x, int y) {
this.x = x;
this.y = y;
}
public void setEndPoint(int x, int y) {
x2 = (x);
y2 = (y);
}
public void drawfillRect(Graphics g, int x, int y, int x2, int y2) {
int px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
//g.fillRect(px, py, pw, ph);
Rectangl rect = new Rectangl(px,y,x2,py,pw,ph,couleur,true);
rect.dessinerfrect(g);
forme.add(rect);
}
}
private void formMousePressed(java.awt.event.MouseEvent evt) {
setStartPoint(evt.getX(), evt.getY());
repaint();
}
private void formMouseReleased(java.awt.event.MouseEvent evt) {{
setEndPoint(evt.getX(), evt.getY());
repaint();
//dessiner(this.getGraphics());
}
}
private void formMouseDragged(java.awt.event.MouseEvent evt){{
setEndPoint(evt.getX(), evt.getY());
repaint();
//dessiner(this.getGraphics());
}
}
As you can see this is the class that does the drawings, the rectangle that will be drawn is an object from a class that I created and this class is a subclass of a super class Forme. As I said previously, the application can draw shapes but the shapes that are drawn are not saved. Also I removed the getters and setters from my post because I wanted to keep only what was essential and I wanted to make my post clearer.
Here is the class Rectangl:
public class Rectangl extends Forme {
private int largeur;
private int hauteur;
private Rectangle rectangle;
public Rectangl(int x1,int y1, int x2 ,int y2,int largeur,int hauteur,Color couleur,Boolean plein){
super(x1,y1,x2,y2,couleur,plein);
this.largeur = largeur;
this.hauteur = hauteur;
}
public void dessinerrect(Graphics g){
g.setColor(couleur);
g.drawRect((int)point1.getX(), (int)point2.getY(), largeur, hauteur);
}
public void dessinerfrect(Graphics g){
g.setColor(couleur);
g.fillRect((int)point1.getX(), (int)point2.getY(), largeur, hauteur);
}
}
You'll need to implement a display list. This is a data structure that represents all the items currently in the drawing. The component painter just traverses the list and draws each item (usually after erasing the screen so that deleted objects don't appear in the new drawing). It also optionally draws the "rubberband cursor" if the mouse has been pressed and not yet released. The mouse actions (usually releasing the mouse button just modify status variables including display list (add, select, delete, etc.) and then repaint the drawing surface so the component painter is called.
A Java ArrayList is a reasonable way to implement a simple display list. The items themselves are a classical use of interfaces and/or inheritance:
interface DisplayListItem {
void draw(Graphics g);
}
abstract class AbstractRectangle implements DisplayListItem {
protected int x, y, w, h;
protected Color color;
Rectangle(int x, int y, int w, int h, Color color) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
}
}
class Rectangle extends AbstractRectangle {
Rectangle(int x, int y, int w, int h, Color color) {
super(x, y, w, h, color);
}
#Override
void draw(Graphic g) {
g.setColor(color);
g.drawRect(x, y, w, h);
}
}
class FilledRectangle extends AbstractRectangle {
FilledRectangle(int x, int y, int w, int h, Color color) {
super(x, y, w, h, color);
}
#Override
void draw(Graphic g) {
g.setColor(color);
g.fillRect(x, y, w, h);
}
}
private List<DisplayListItem> displayList = new ArrayList<>();
private int xPress, yPress, xDrag, yDrag;
private boolean mousePressed = false;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (DisplayListItem item : displayList) {
item.draw(g);
}
if (mousePressed) {
// Draw the click-and-drag cursor.
g.setColor(Color.RED);
g.drawRect(xPress, yPress, xDrag - xPress, yDrag - yPress);
}
}
private void formMousePressed(MouseEvent evt) {
xPress = evt.getX();
yPress = evt.getY();
mousePressed = true;
}
private void formMouseDragged(MouseEvent evt) {
if (!mousePressed) return;
xDrag = evt.getX();
yDrag = evt.getY();
repaint();
}
private void formMouseReleased(MouseEvent evt) {
if (!mousePressed) return;
xDrag = evt.getX();
yDrag = evt.getY();
// Adding a rectangle to the display list makes it permanent.
displayList.add(new Rectangle(xPress, yPress, xDrag - xPress, yDrag - yPress));
mousePressed = false;
repaint();
}
Caveat: This is uncompiled, untested code. Use at your own risk.
Swing has the useful Shape interface which has been implemented into several concrete classes that could serve your purpose well.
There are several different Shapes (Ellipse2D, Rectangle2D, RoundRectangle2D) are stored in an ArrayList of Shape objects, and then these are drawn within the JPanel's paintComponent method after first casting the Graphics object into a Graphics2D.

Error:: VR_Video is not abstract and does not override abstract method [duplicate]

So I've been working on a homework on abstraction for my programming class and fell into a problem. The goal for me right now is to be able to use abstraction, then later be able to draw with rectangles and ovals a simple city, like a rectangular building or a oval light on a light post.
The error I am receiving when I compile is: MyTestApp.Rectangle is not abstract and does not override abstract method drawEllipse(java.awt.Graphics) in MyTestApp.Shape. This Error shows up on the line "class Rectangle extends Shape{" right below the class Shape.
My question is what am I doing wrong with my abstraction? I've been messing with the constructors and draw() methods in classes Rectangle and Ellipse for a while now and still to no luck happen to find a solution.
Code is below:
import java.awt.*;
import javax.swing.*;
public class MyTestApp extends JPanel {
Rectangle rect;
Ellipse oval;
public static void main(String [] args) {
MyTestApp myTestApp = new MyTestApp ();
myTestApp.test();
}
public MyTestApp () { //creates the jframe
JFrame frame = new JFrame("MyClass Driver");
setBackground(new Color(200, 250, 200));
setPreferredSize(new Dimension(500, 400));
frame.add(this);
frame.pack();
frame.setVisible(true);
}
public void delay(int msecs) {
try {
Thread.sleep(msecs);
} catch (InterruptedException e) {
}
}
public void paint(Graphics g) {//paints the rectangle and ellipse
super.paint(g);
if (rect != null)
rect.drawRectangle(g);
if (oval != null)
oval.drawEllipse(g);
}
public void test() {//gives the x/y position, width/height, and fill/outline color for the rectangle and oval
delay(1000);
rect = new Rectangle(20, 30, 23, 75, Color.GREEN, Color.BLUE);
oval = new Ellipse(10, 10, 10 , 34, Color.RED, Color.MAGENTA);
repaint();
}
public abstract class Shape{//abstract class Shape that sets the x/y, width/height, and colors for the shapes
private int x, y, width, height;
private Color fillColor;
private Color outlineColor;
public Shape(int x, int y, int width, int height, Color fillColor, Color outlineColor) {
setXY(x, y);
setSize(width, height);
setFillColor(fillColor);
setOutlineColor(outlineColor);
}
public boolean setXY(int x, int y) {
this.x = x;
this.y = y;
return true;
}
public void setSize(int width, int height) {
if (width > 0)
this.width = width;
if (height > 0)
this.height = height;
}
public boolean setFillColor(Color fillColor){
if (fillColor == null) return false;
this.fillColor = fillColor;
return true;
}
public boolean setOutlineColor(Color outlineColor){
if (outlineColor == null) return false;
this.outlineColor = outlineColor;
return true;
}
public Color getFillColor() {
return fillColor;
}
public Color getOutlineColor() {
return outlineColor;
}
public abstract void drawRectangle(Graphics g);//do i need two?
public abstract void drawEllipse(Graphics g);//do i need both?
}
class Rectangle extends Shape{//!!!!!!!!!! where the error shows
public Rectangle(int x, int y, int width, int height, Color fillColor, Color outlineColor) {
super(x, y, width, height, fillColor, outlineColor);
}
public void drawRectangle(Graphics g){//draws the retangle
g.setColor(fillColor);
g.fillRect(x, y, width, height);
g.setColor(outlineColor);
g.drawRect(x, y, width, height);
}
}
class Ellipse extends Shape{
public Ellipse(int x, int y, int width, int height, Color fillColor, Color outlineColor) {
super(x, y, width, height, fillColor, outlineColor);
}
public void drawEllipse(Graphics g){//draws the ellipse
g.setColor(fillColor);
g.fillOval(x, y, width, height);
g.setColor(outlineColor);
g.drawOval(x, y, width, height);
}
}
}
Thanks for reading and helping!
Both classes Rectangle and Ellipse need to override both of the abstract methods.
To work around this, you have 3 options:
Add the two methods
Make each class that extends Shape abstract
Have a single method that does the function of the classes that will extend Shape, and override that method in Rectangle and Ellipse, for example:
abstract class Shape {
// ...
void draw(Graphics g);
}
And
class Rectangle extends Shape {
void draw(Graphics g) {
// ...
}
}
Finally
class Ellipse extends Shape {
void draw(Graphics g) {
// ...
}
}
And you can switch in between them, like so:
Shape shape = new Ellipse();
shape.draw(/* ... */);
shape = new Rectangle();
shape.draw(/* ... */);
Again, just an example.
If you're trying to take advantage of polymorphic behavior, you need to ensure that the methods visible to outside classes (that need polymorphism) have the same signature. That means they need to have the same name, number and order of parameters, as well as the parameter types.
In your case, you might do better to have a generic draw() method, and rely on the subclasses (Rectangle, Ellipse) to implement the draw() method as what you had been thinking of as "drawEllipse" and "drawRectangle".

Implementing java mouse listeners, custom gui

I'm working on a game currently using slick2d + lwjgl and I am trying to implement listeners for the gui components. I was wondering on how to do that since I am currently stumped. I was thinking I could do something like this
GuiComponent class....
public void addListener(MouseAdapter e){
// Stuck on this part
}
Than implement it into a menu like this
gComponent.addListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
// listener logic
}
}
I don't know how to actually trigger the method mouseClicked inside the addListener method, because when i ran it like this nothing happened unless I am delusional. Anyway, any help does help even if you just send me to a javadoc or something like that. Thanks guys & merry christmas :)
EDIT:
GuiComponent class
package com.connorbrezinsky.turbulent.gui;
import java.awt.event.MouseAdapter;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
public class GuiComponent {
int x, y, width, height;
Color color;
Image i;
public GuiComponent(Gui gui, int _x, int _y, int w, int h, Color c) {
gui.components.add(this);
x = _x;
y = _y;
width = w;
height = h;
color = c;
}
public GuiComponent(int _x, int _y, int w, int h, Color c) {
x = _x;
y = _y;
width = w;
height = h;
color = c;
}
public GuiComponent(Gui gui, int _x, int _y, int w, int h) {
gui.components.add(this);
x = _x;
y = _y;
width = w;
height = h;
color = Color.white;
}
public GuiComponent(int _x, int _y, int w, int h) {
x = _x;
y = _y;
width = w;
height = h;
color = Color.white;
}
public void addText(String s){
}
public void addSprite(Image s){
i = s;
}
public void render(Graphics g){
if(i == null) {
g.setColor(color);
g.fillRect(x, y, width, height);
}else{
i.draw(x,y,width,height);
}
}
public void addListener(MouseAdapter e){
// stuck here
}
}
Example in menu class
GuiComponent guiTest = new GuiComponent(20, 20, 50, 10);
public void update(GameContainer arg0, StateBasedGame arg1, int arg2) throws SlickException{
guiTest.addListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
System.out.println("click");
}
});
}
Slick2D offers several components, I don't know if you've seen them. Maybe can you use the AbstractComponent, by inherits from it to do what you expect. It seems to provide the addListeners method that you want to implement by yourself. It say simplify you own code.
Then to add a listener, you can use your gameContainer. Through gc.getInput().addListener().
With your code it would be something like :
GuiComponent guiTest = new GuiComponent(20, 20, 50, 10);
public void update(GameContainer arg0, StateBasedGame arg1, int arg2) throws SlickException{
arg0.getInput().addListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
System.out.println("click");
}
});
}

Categories

Resources