The code i tried is rotating the image but i want to rotate the image vertically like rotating earth at 360 degrees with 0 inclination
The code i tried is
public class MainClass extends JPanel {
static ImageIcon icon = null;
static RotatedIcon rotate = null;
static JLabel label = null;
public MainClass() {
try {
BufferedImage wPic = ImageIO.read(this.getClass().getResource(
"globe.png"));
icon = new ImageIcon(wPic);
rotate = new RotatedIcon(icon, 180);
label = new JLabel(rotate);
} catch (Exception e) {
System.out.println("raise exception");
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
label.repaint();
}
public static void main(String[] args) throws IOException,
InterruptedException {
MainClass mainClass = new MainClass();
JFrame frame = new JFrame();
mainClass.add(label);
frame.add(mainClass);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
ActionListener taskPerformer = new ActionListener() {
int degree = 360;
public void actionPerformed(ActionEvent evt) {
rotate.setDegrees(degree);
degree = degree + 90;
label.repaint();
mainClass.repaint();
}
};
Timer timer = new Timer(1000, taskPerformer);
// timer.setRepeats(false);
timer.start();
Thread.sleep(5000);
}
}
https://tips4java.wordpress.com/2009/04/06/rotated-icon/ Reference link of the RotatedIcon class i used.
As Explained am able to rotate image but that is not vertically.
If you only have a flat 2D image of the world then then best you might be able to do is use the Marquee Panel.
The Marquee Panel will allow you to scroll the image and you can set it to wrap when it reaches the end. You won't get a 3D effect buy you will scroll around the world with a flat 2D image.
Related
So i'm trying to clear my drawing Panel and I have looked at multiple examples but none of them seem to be working for me? I have a clear button that clears textfields/errors which I got to work perfectly but the Drawing panel still does not clear arraylists or "repaint".
I'm playing around with changing around the size of the oval so please ignore my drawPoints method.
Here is my code:
public class Panel extends JPanel{
ArrayList<Point> pointArray = new ArrayList<>();
ArrayList<Color> colorArray = new ArrayList<>();
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
repaint();
//Create the 2D graphics object
Graphics2D myDrawing = (Graphics2D) g;
for (int i = 0; i < pointArray.size(); i++) {
myDrawing.setColor(colorArray.get(i));
myDrawing.fillOval(pointArray.get(i).x,pointArray.get(i).y, 10, 10);
}
}
public void drawPoints(int mouseX, int mouseY, int height, int width){
Point p = new Point(mouseX,mouseY);
pointArray.add(p);
colorArray.add(this.getForeground());
repaint();
}
public void changeColor(){
int red = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
this.setForeground(new Color(red,green,blue));
}
public void mousePressed(MouseEvent event) {
pointArray.clear();
colorArray.clear();
repaint();
}
}
public static void main(String[] args) {
//set the frame
JFrame frame = new JFrame();
frame.setSize(600, 300);
frame.setTitle("Multiple Panels");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create the panel for GUI
JPanel panelGUI = new JPanel();
panelGUI.setBackground(Color.yellow);
//GUIs
//create textfields
JTextField radiusField1 = new JTextField("10", 10);
JTextField radiusField2 = new JTextField("10", 10);
//create buttons
final JButton clearDrawingButton = new JButton("Clear Screen");
final JButton changeColorButton = new JButton("Change Color");
//labels
final JLabel displayLabel = new JLabel("");
//add all GUIs to the GUI panel
panelGUI.add(radiusField1);
panelGUI.add(radiusField2);
panelGUI.add(changeColorButton);
panelGUI.add(clearDrawingButton);
panelGUI.add(displayLabel);
//create the panel to draw
final Panel drawingPanel = new Panel();
drawingPanel.setBackground(Color.white);
//create the initial color
Color drawingColor = new Color(255,0,0);
//set the initial drawing color of the panel
drawingPanel.setForeground(drawingColor);
//add the grid with two columns and two rows to add the three panels
GridLayout grid = new GridLayout(0,2,10,20);
//add the grid to the frame
frame.setLayout(grid);
//add the panels to the frame
frame.add(panelGUI);
frame.add(drawingPanel);
class MouseClickListener implements MouseListener
{
public void mouseClicked(MouseEvent event)
{
int x = event.getX();
int y = event.getY();
System.out.println(x + " " + y);
try {
String text1 = radiusField1.getText();
String text2 = radiusField2.getText();
int height = Integer.parseInt(text1);
int width = Integer.parseInt(text2);
drawingPanel.drawPoints(x, y, height, width);
} catch (NumberFormatException ex) {
displayLabel.setText("Textfields empty! Please enter number.");}
}
// Donothing methods
public void mouseReleased(MouseEvent event) {}
public void mousePressed(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
}
class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource()== changeColorButton){
drawingPanel.changeColor();
}
if(event.getSource()==clearDrawingButton){
radiusField1.setText("10");
radiusField2.setText("10");
displayLabel.setText("");
}
}
}
MouseListener listener1 = new MouseClickListener();
drawingPanel.addMouseListener(listener1);
ActionListener listener = new ButtonListener();
changeColorButton.addActionListener(listener);
clearDrawingButton.addActionListener(listener);
frame.setVisible(true);
}
}
I have a clear button that clears textfields/errors which I got to work perfectly but the Drawing panel still does not clear arraylists or "repaint".
Well look at the code that clears the text fields:
if(event.getSource()==clearDrawingButton){
radiusField1.setText("10");
radiusField2.setText("10");
displayLabel.setText("");
}
Where is the code that clears the ArrayLists?
Add the code to clear the ArrayLists to the ActionListener.
You can also check out Custom Painting Approaches for working code that draws "rectangles". It supports different colors and a "Clear" button.
Also, instead of using a JTextField for the oval size, you might want to consider using a JSpinner. This will allow the user to easily change the numeric value and you don't have to add any special editing to make sure the value entered is a number.
You have this mousePressed method in your main class:
public void mousePressed(MouseEvent event) {
pointArray.clear();
colorArray.clear();
repaint();
}
But it isn't doing anything because your main class does not implement MouseListener and no one is calling this method.
The rest of your code is not very pretty looking. I assume you are doing this as part of a course or otherwise just trying to learn Java Swing in a non-work environment. If this is true, I would recommend that you start over - at least with your MouseListeners, and instead create Actions for your button responses by subclassing AbstractAction and using it with JButton.setAction(myAction); This may seem painful now, but you'll be glad you did it in the future
By using Java swing, what available approach are there to create a foreground image (such as an image of a knight) which is movable on a static background image?
Shall we use JLabel with image icons?
This solution also addresses the issues mentioned in: Images In JFrame are overwriting each other not displaying both images over eachother
If we try to add a background and some foreground images, it can be a little tricky if we intend to let those images overlap each other as many layouts provided by Java may prevent components (such as JLabels) from overlapping each other. Positioning the images to the exact location can be an issue too.
I will suggest a different approach when we want to create a screen similar to those we see in games:
Instead of creating multiple JLabel filled with imageIcon, an alternative will be drawing directly on the panel. This is a customized panel with instances of images we are interested to draw.
class DrawingSpace extends JPanel
{
private BufferedImage bg, hero;
private int bgWidth, bgHeight;
private int heroWidth, heroHeight;
private int scWidth, scHeight;
private int mouseX, mouseY;
public DrawingSpace(){
loadImages();
init();
setPreferredSize(new Dimension(scWidth, scHeight));
addMouseMotionListener(new MouseHandler());
}
private void init(){
mouseX = 0;
mouseY = 0;
heroWidth = hero.getWidth();
heroHeight = hero.getHeight();
bgWidth = bg.getWidth();
bgHeight = bg.getHeight();
scWidth = bgWidth;
scHeight = bgHeight;
}
private void loadImages(){
try{
bg = ImageIO.read(getClass().getResource("Images/background.jpg"));
hero = ImageIO.read(getClass().getResource("Images/knight.png"));
}catch(IOException ioe){System.out.println("Unable to open file");}
}
#Override public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(bg, 0, 0, bgWidth, bgHeight, null);
g.drawImage(hero, mouseX-(heroWidth/2), mouseY-(heroHeight/2), heroWidth, heroHeight, null);
}
private class MouseHandler implements MouseMotionListener
{
#Override public void mouseMoved(MouseEvent e){
mouseX = e.getX();
mouseY = e.getY();
repaint();
}
#Override public void mouseDragged(MouseEvent e){}
}
}
A runner class to drive the codes:
class KnightRunner
{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
JFrame frame = new JFrame("Knight Runner");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawingSpace());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I have JPanel inside JFrame and there are more than one BufferedImages in the JPanel like this.
Now my question is how can i move the BufferedImages inside the JPanel? More specifically How to add MouseEventhandler to the Buffered Images?. Though I can drag JPanel from the code below but can't figure out how to drag Buffered Images inside JPanel. Thanks for the help.
I have three classes like this
MainWindow.Java
public class MainWindow extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
}
}
});
}
public MainWindow() {
JFrame frame = new JFrame();
.... // Other code of JFrame
JPanel panel_3 = new JPanel();
.... // other code of JPanel
frame.getContentPane().add(panel_3);
panel_3.setLayout(new BorderLayout(0, 0));
Drawing drawingObj = new Drawing();
panel_3.removeAll();
panel_3.add(drawingObj );
drawingObj .revalidate();
drawingObj .repaint();
BasicDragging drag= new BasicDragging();
panel_3.addMouseListener(drag);
panel_3.addMouseMotionListener(drag);
}
}
Drawing.java
public class Drawing extends JPanel {
private BufferedImage Image1 ;
private BufferedImage Image2;
private BufferedImage Image3;
public Drawing() {
try {
Image1 = ImageIO.read(new File("path of file"));
Image2 = ImageIO.read(new File("path of file"));
Image3 = ImageIO.read(new File("path of file"));
}
catch (IOException ex) {
// handle exception...
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(Image1 , 150, 10, null);
g.drawImage(Image2 , 150, 70,null);
// Other code of drawing images
}
}
}
BasicDragging.java
public class BasicDragging extends MouseInputAdapter{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me)
{
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
Instead of using images and then writing code to determine which image has "been clicked" you can just use a JLabel with an ImageIcon to display the image. Then you can add your MouseListener to the JLabel and drag the label around the panel.
Using this approach the basic code for dragging components would be:
public class DragListener extends MouseInputAdapter
{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me)
{
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
The code to use this class would be:
DragListener drag = new DragListener();
component.addMouseListener( drag );
component.addMouseMotionListener( drag );
You can also check out the Component Mover which adds some more advanced dragging features.
You will need to use a null layout on the panel and set the size/location of the label. So you may want to use the Drag Layout which simplifies this process for you.
My first suggestion would be a simple one...
As you can see you draw these images by coordinates, x and y.
You could add the MouseListener to JPanel. That's where the magic already happens and it would be rather confusing if you create more objects.
Now you only have to check if the mouse hover above a image and is pressed.
You only need to calculate the size and if the point is inside the image.
If it is inside the image moves in the direction of the mouse.
And you shouldn't reset the position rather move it along.
That's how it is done.
Just set the x and y for the images when the are clicked and pressed on.
I'd create an object DragImage which contains the core BufferedImage + coordinates that represent the x and y and it's size. Additionally i'd add a function that calculates public boolean isHovering(int x, int y).
It should work out. And the x and y coordinates are used in your draw function.
I hope you understand what i was trying to say
PaintComponent doest paint figures. Just nothing is happening, clean Jframe appear.
I think something is wrong with list or with the way i called method
List is in class with Paint Component
public class Paint extends JPanel implements ActionListener {
List<Figures> figuresList = new ArrayList<Figures>();
Timer t = new Timer(5, this);
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Figures figure : figuresList) {
figure.drawItself(g, figure.getLocationX(), figure.getLocationY());
}
t.start();
}
#Override
public void actionPerformed(ActionEvent e) {
{
for (Figures figure : figuresList) {
if (figure.getLocationX() < 0 || figure.getLocationX() > 540) {
figure.setVelocityX(-figure.getVelocityX());
}
if (figure.getLocationY() < 0 || figure.getLocationX() > 220) {
figure.setVelocityY(-figure.getVelocityY());
}
figure.setLocationX(figure.getLocationX()
+ figure.getVelocityX());
figure.setLocationY(figure.getLocationY()
+ figure.getVelocityY());
}
}
repaint();
}
And drawitself:
public class Circle implements Figures {
public int locationX = 12;
public int locationY = 12;
public int velocityX =1;
public int velocityY =1;
public void drawItself(Graphics g, int locationX, int locationY){
this.locationX = locationX;
this.locationY = locationY;
g.drawOval(locationX, locationY, 40, 40);
g.fillOval(locationX, locationY, 40, 40);
}
Main:
public static void main(String[] args) {
Circle c = new Circle();
Quadrat q = new Quadrat();
Paint p = new Paint();
p.figuresList.add(c);
p.figuresList.add(q);
GUI.Configuration();
}
GUI
public class GUI {
public static void Configuration(){
JFrame frame = new JFrame("Figures Animation");
frame.setSize(600,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new Paint();
frame.getContentPane().add(BorderLayout.CENTER, panel);
}
You create and add a Paint instance here:
public class GUI {
public static void Configuration(){
JFrame frame = new JFrame("Figures Animation");
frame.setSize(600,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new Paint(); // *** new Paint is here, but nothing is added
frame.getContentPane().add(BorderLayout.CENTER, panel);
}
But nothing of use has been added to it. All the important stuff is added to a completely different Paint JPanel, one that is never displayed:
public static void main(String[] args) {
Circle c = new Circle();
Quadrat q = new Quadrat();
Paint p = new Paint(); // **** ANOTHER new Paint is here, and it gets goodies
p.figuresList.add(c);
p.figuresList.add(q);
// but is never added to a JFrame and is never displayed.
GUI.Configuration();
}
Don't do this. Create one Paint JPanel, one only, add the important components to it, and then only add that one to the JFrame. Most important, don't just type in code, think and plan your program before committing it to code, and you won't see errors like this.
Also, and again, do not start a Timer from within paintComponent and don't create Circle there. You can draw your Circle instance in paintComponent, but create it and start your Timer within the Paint constructor.
Hi i am looking for a way to rescale my image and still show the entire image, so it isn't cut in half or something like that. I am also not allowed to use libraries of any sort. Im drawing the image with paintcomponent.
Is there any way how to do this properly?
I've tried this one already :
BufferedImage image = null;
try {
image = ImageIO.read(new File($question.getMediaFile().getPath())); /* Get the image */
Image scaled = image.getScaledInstance(350, 350, Image.SCALE_SMOOTH);
g.drawImage(scaled, w-350, 200, null);
} catch (IOException e) {
e.printStackTrace();
}
This resizes my image but doesn't show the entire image, i would like to rescale it to an image with 300*300 or 350*350 size or something like that.
Thanks!
Using the getScaledInstance() method works fine for me. Here's the code i was testing with:
public class Resize {
public static void main(String[] args) throws Exception {
final Image logo = ImageIO.read(new URL("http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png"));
final Dimension dim = new Dimension(logo.getWidth(null), logo.getHeight(null));
final JFrame frame = new JFrame();
frame.add(new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(logo.getScaledInstance(dim.width, dim.height, 0), 0, 0, this);
}
});
final JSlider xSlider = new JSlider(JSlider.HORIZONTAL, 1, dim.width*3, dim.width);
final JSlider ySlider = new JSlider(JSlider.VERTICAL, 1, dim.height*3, dim.height);
ChangeListener cl = new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
dim.width = xSlider.getValue();
dim.height = ySlider.getValue();
frame.repaint();
}
};
xSlider.addChangeListener(cl);
ySlider.addChangeListener(cl);
frame.add(xSlider, "South");
frame.add(ySlider, "East");
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}