JButton accessible for several Panels - class

I'm new at Java Programming and have "beginner Question".
I already tried to find wether someone already had the same problem, but I couldn't find any posts which were on my low level.
My Problem:
I have 2 JPanels in one of them, (let's call it Panel1) I implements a JTextField (field1) and a JButton (button1). on Panel2 I want to draw something, depending on what the using tipped in the first JTextField.
My Problem is I want Panel2 to "see" that button1 (in Panel1) , which I don't manage to do.
Can anyone give me a hint, a Youtube Video or something like that, where I can see a nice example where someone handles such a Problem?
Greetings Ventura
P.S I had an idea to pass values to Panel2 where it should draw those things I want, here my code up so far (I hope I post it correctly): Here Panel1:
public class Panel1 extends JPanel
{
public JButton button = new JButton("OK");
public JTextField field1 = new JTextField(5);
public String name;int b;
public Panel1()
{
setBackground(Color.WHITE);
add(field1);
add(button);
ButtonListener listener = new ButtonListener(field1);
button.addActionListener(listener);
}
public Dimension getPreferredSize()
{
return new Dimension(400,400);
}
}
Here the ButtonListener :
class ButtonListener implements ActionListener
{
Graphics g;
//Graphics2D g2 = (Graphics2D) g;
public Panel2 pan2 = new Panel2();
public String name;
public JTextField field1 = new JTextField();
int b;
public ButtonListener(JTextField field1)
{this.field1 = field1;}
public void actionPerformed(ActionEvent e)
{
String op = e.getActionCommand();
if(op.equals("OK"))
{
name = field1.getText();
try
{
b = Integer.parseInt(name);
JOptionPane.showMessageDialog(null,"Ihre Zahl = "+b);
pan2.setvalue(b,g);
}
catch(NumberFormatException ex) {JOptionPane.showMessageDialog(null,"Please enter real numbers!");}
}
}
}
And finally Panel2 where I'd like to draw things based on the Input given in Panel1 (for example: I type in 10 and he draws me a Rectangle with width 10 or something like that)
public class Panel2 extends JPanel
{
Graphics g;
Graphics2D g2 = (Graphics2D) g;
public int b;
public Panel2()
{
setBackground(Color.YELLOW);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g);
g2.setColor(Color.RED);
g2.fillRect(200, 200, 50, 50);
Paint2(g);
}
public void Paint2(Graphics g)
{
this.g = g;
Graphics2D g2 = (Graphics2D) g;
//super.paintComponent(g);
System.out.println("TEST2");
g2.setColor(Color.BLUE);
//System.out.println("TEST3");
g2.fillRect(10 , 10, 40, 40);
}
public void setvalue(int b, Graphics g)
{
this.b = b;
this.g = g;
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.CYAN);
g2.fillRect(0, 0, 40, 40);
System.out.println("B ist gleich = "+b);
//Paint2(g2);
}
public Dimension getPreferredSize()
{
return new Dimension(400,400);
}
I'm sorry if it is a little cumbersome to read.
My basic Problem I get in this code is the NullpointerException in Panel2 when I want to call the Method
setvalue(int b, Graphics g)
g2.setColor(Color.Cyan)
Greetings Patrick

I did a redesign to most of Panel1 and a little bit to Panel2.
I'm going to start with Panel2 because it's simpler. Here is the new code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Panel2 extends JPanel {
Graphics g;
Graphics2D g2;
public int b;
public Panel2() {
setBackground(Color.YELLOW);
b = 50;
}
#Override
public void paintComponent(Graphics g) {
g2 = (Graphics2D) g;
super.paintComponent(g);
g2.setColor(Color.RED);
g2.fillRect(200, 200, 50, 50);
g2.setColor(Color.BLUE);
g2.fillRect(10, 10, 40, 40);
g2.setColor(Color.CYAN);
g2.fillRect(b, b, 40, 40);
}
public void setValue(int b) {
this.b = b;
System.out.println("B ist gleich = " + b);
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
The biggest change that I made to Panel2 is that I made g2 a class variable that all the methods can use. Instead of making the methods take a Graphics variable each time, I just made it so that they can use the one from the class. I also didn't make a new Graphics2D variable "equal" anything each time the method was called because there was no need for that. The only place I updated it in was the paintComponent() method so that I could update it once for the whole class.
Next up is Panel1. Here is the code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Panel1 extends JPanel {
public JButton button = new JButton("OK");
public JTextField field1 = new JTextField(5);
public String name;
int b;
private Panel2 pan2;
public Panel1() {
setBackground(Color.WHITE);
add(field1);
add(button);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String op = e.getActionCommand();
if (op.equals("OK")) {
name = field1.getText();
try {
b = Integer.parseInt(name);
pan2.setValue(b);
JOptionPane.showMessageDialog(null, "Ihre Zahl = " + b);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null, "Please enter real numbers!");
}
}
}
};
button.addActionListener(listener);
}
public void setSecondPanel(Panel2 panel) {
pan2 = panel;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Panel1 pan1 = new Panel1();
Panel2 pan2 = new Panel2();
pan1.setSecondPanel(pan2);
frame.setSize(pan1.getPreferredSize().width + pan2.getPreferredSize().width, pan1.getPreferredSize().height);
frame.add(pan2, BorderLayout.EAST);
frame.add(pan1, BorderLayout.WEST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
First of all, notice how I didn't create a ButtonListener. Because you're only using it once, there's no need to create a new class for it (it's also less code).
In the main() method, I made it so that it adds both panels to the opposite sides so that they won't overlap each other or anything.
Finally, I created a setSecondPanel method in the Panel1 class so that the class would have a Panel2 variable to work with at any time.

Related

Implement undo/redo button in JavaFX [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 months ago.
Improve this question
Ive been scrolling and scrolling and i dont seem to find any solution. I am making a simple java fx program where i draw different shapes. The problem is that i dont know how to implement an undo button. I have found that you can use stacks, command pattern, arraydeque and so on... But i cant fix it..
Here is some of the code.
public class shapeModel {
//private final List<Shape> undoHistory = new ArrayList<>();
//private final Deque<Deque<Shape>> redoHistory;
private final ObservableList<Shape> shapeList;
private final ObjectProperty<Color> colorPickerSelect;
private final int historyIndex = -1;
private ShapeType currentShape;
public shapeModel() {
//this.redoHistory = new ArrayDeque<>();
this.colorPickerSelect = new SimpleObjectProperty<>(Color.GREEN);
this.shapeList = FXCollections.observableArrayList(shape -> new Observable[]{
shape.colorProperty()
});
}
public ShapeType getCurrentShape() {
return currentShape;
}
public void setCurrentShape(ShapeType currentShape) {
this.currentShape = currentShape;
}
public void addShapes(Shape shape) {
if (!(shape == null))
this.shapeList.add(shape);
}
public Color getColorPickerSelect() {
return colorPickerSelect.get();
}
public ObjectProperty<Color> colorPickerSelectProperty() {
return colorPickerSelect;
}
public ObservableList<Shape> getShapeObservableList() {
return shapeList;
}
public void undo() {
}
}
Controller class:
public class HelloController {
public Button eraserButton;
public Button undoButton;
public BorderPane scenePane;
public ColorPicker myColorPicker;
public ChoiceBox<String> myChoiceBox;
public GraphicsContext context;
public Canvas canvas;
public shapeModel model;
public void initialize() {
context = canvas.getGraphicsContext2D();
model.getShapeObservableList().addListener((ListChangeListener<Shape>) e -> listChanged());
myColorPicker.valueProperty().bindBidirectional(model.colorPickerSelectProperty());
}
public HelloController() {
this.model = new shapeModel();
}
//
// private int count = 0;
//
// private final Shape[] shapes = new Shape[30];
public void canvasClicked(MouseEvent mouseEvent) {
Shape shape = Shape.creatingShapes(model.getCurrentShape(),mouseEvent.getX(),mouseEvent.getY(),50,50,myColorPicker.getValue());
model.addShapes(shape);
// redraw();
// shapes[count] = shape;
// count++;
// paintCanvas();
}
public void listChanged() {
var context = canvas.getGraphicsContext2D();
model.getShapeObservableList().forEach(s -> s.draw(context));
}
public void undoClicked() {
}
// public void redo() {
//
// if(historyIndex < model.getShapeObservableList().size()-1) {
// historyIndex++;
// model.getShapeObservableList(),(historyIndex).
// }
//
// }
public void handleClick() {
FileChooser chooser = new FileChooser();
File file = chooser.showSaveDialog(scenePane.getScene().getWindow());
}
public void onCircleClicked(ActionEvent e) {
model.setCurrentShape(ShapeType.CIRCLE);
}
public void onRectangleClicked(ActionEvent e) {
model.setCurrentShape(ShapeType.RECTANGLE);
}
public void exitAction(ActionEvent actionEvent) {
Platform.exit();
}
public void eraser() {
context.setFill(Color.WHITE);
context.fillRect(0,0,canvas.getWidth(), canvas.getHeight());
// context.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
}
}
Maybe this can help. This is my first time attempting something like this. The experts may have a better, more efficient way of doing this.
My idea was to keep up with a List of WritableImages as you draw. Use that list to go forward and backward through history.
Main
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundImage;
import javafx.scene.layout.BackgroundPosition;
import javafx.scene.layout.BackgroundRepeat;
import javafx.scene.layout.BackgroundSize;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
/**
* Code from: #web http://java-buddy.blogspot.com/
*/
public class App extends Application {
Canvas canvas = new Canvas(400, 400);
StackPane spCanvasHolder = new StackPane(canvas);
List<WritableImage> history = new ArrayList();
AtomicInteger currentlyDisplaying = new AtomicInteger();
#Override
public void start(Stage primaryStage) {
final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
initDraw(graphicsContext);
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, (MouseEvent event) ->
{
graphicsContext.beginPath();
graphicsContext.moveTo(event.getX(), event.getY());
graphicsContext.stroke();
history.add(spCanvasHolder.snapshot(new SnapshotParameters(), null));
System.out.println("Current Display: " + currentlyDisplaying.incrementAndGet());
});
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, (MouseEvent event) ->
{
graphicsContext.lineTo(event.getX(), event.getY());
graphicsContext.stroke();
history.add(spCanvasHolder.snapshot(new SnapshotParameters(), null));
System.out.println("Current Display: " + currentlyDisplaying.incrementAndGet());
});
canvas.addEventHandler(MouseEvent.MOUSE_RELEASED, (MouseEvent event) ->
{
System.out.println("History size: " + history.size());
});
Button btnForwardHistory = new Button(">");
btnForwardHistory.setOnAction((t) ->
{
if(currentlyDisplaying.get() < history.size())
{
File file = new File("CanvasTemp.png");
try
{
canvas.getGraphicsContext2D().clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
ImageIO.write(SwingFXUtils.fromFXImage(history.get(currentlyDisplaying.incrementAndGet()), null), "png", file);
BackgroundImage bI = new BackgroundImage(new Image(new FileInputStream(file)), BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT);
spCanvasHolder.setBackground(new Background(bI));
}
catch (Exception s) {
System.out.println(s.toString());
}
}
});
Button btnBackwardHistory = new Button("<");
btnBackwardHistory.setOnAction((t) ->
{
System.out.println("Current Display: " + currentlyDisplaying.get());
if(currentlyDisplaying.get() > 0)
{
File file = new File("CanvasTemp.png");
try
{
canvas.getGraphicsContext2D().clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
ImageIO.write(SwingFXUtils.fromFXImage(history.get(currentlyDisplaying.decrementAndGet()), null), "png", file);
BackgroundImage bI = new BackgroundImage(new Image(new FileInputStream(file)), BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT);
spCanvasHolder.setBackground(new Background(bI));
}
catch (Exception s) {
System.out.println(s.toString());
}
}
});
VBox vbHistoryControls = new VBox(btnBackwardHistory, btnForwardHistory);
StackPane root = new StackPane();
root.getChildren().add(new HBox(vbHistoryControls, spCanvasHolder));
Scene scene = new Scene(root);
primaryStage.setTitle("java-buddy.blogspot.com");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void initDraw(GraphicsContext gc){
double canvasWidth = gc.getCanvas().getWidth();
double canvasHeight = gc.getCanvas().getHeight();
gc.setFill(Color.LIGHTGRAY);
gc.setStroke(Color.BLACK);
gc.setLineWidth(5);
gc.fill();
gc.strokeRect(
0, //x of the upper left corner
0, //y of the upper left corner
canvasWidth, //width of the rectangle
canvasHeight); //height of the rectangle
gc.setFill(Color.RED);
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
}
}
module-info
module com.mycompany.javafxsimpletest {
requires javafx.controls;
requires javafx.swing;
exports com.mycompany.javafxsimpletest;
}
Output
I would not use this code in a production app, but maybe the ideas can get you in the right direction.
This example is based on the UndoFX framework:
https://github.com/FXMisc/UndoFX
I offer up the example without a lot of explanation. You could study and learn from it or ignore it. It isn't going to do exactly what you want, but there might be some useful ideas from it for you.
The example:
Uses the scene graph instead of a Canvas.
Only adds shapes to a pane.
Provides the ability to remove the added shapes and add them back again.
The example is probably overcomplicated for the limited functionality it provides but might be structured in such a way that it is more easily adaptable to adding additional functionality.
The example does not demonstrate manipulating shapes (such as selecting them, changing their border and fill colors, changing their sizes, etc) and undoing or redoing such changes. But if you wanted to extend functionality for that, you could use the app as a basis and look into the UndoFX demo app which shows how to apply undo and redo to multiple properties on a shape. Depending on the functionality added, this could be quite a difficult task as generic undo/redo across a wide range of functionality is inherently difficult (IMO).
com/example/shapechanger/ShapeChangerApp.java
package com.example.shapechanger;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import org.fxmisc.undo.UndoManager;
import org.fxmisc.undo.UndoManagerFactory;
import org.reactfx.EventSource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class ShapeChangerApp extends Application {
#Override
public void start(Stage stage) {
Model model = new Model();
EventSource<ShapeChange> changes = new EventSource<>();
UndoManager<ShapeChange> undoManager = new UndoProvider(changes).getUndoManager();
Ribbon ribbon = new Ribbon(model, undoManager);
DrawingPane drawingPane = new DrawingPane(model, changes);
ScrollPane scrollPane = new ScrollPane(drawingPane);
scrollPane.setPrefSize(300, 300);
VBox layout = new VBox(ribbon, scrollPane);
VBox.setVgrow(scrollPane, Priority.ALWAYS);
Scene scene = new Scene(layout);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
class DrawingPane extends Pane {
private static final double DRAWING_PANE_SIZE = 1_000;
private final Model model;
private final EventSource<ShapeChange> changes;
private final ShapeFactory shapeFactory = new ShapeFactory();
public DrawingPane(Model model, EventSource<ShapeChange> changes) {
this.model = model;
this.changes = changes;
setOnMouseClicked(e -> addShape(e.getX(), e.getY()));
setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
setPrefSize(DRAWING_PANE_SIZE, DRAWING_PANE_SIZE);
setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
}
private void addShape(double x, double y) {
DrawableShape drawableShape = model.selectedShapeProperty().get();
Shape shape = shapeFactory.create(
drawableShape, x, y
);
ShapeChange shapeChange = new ShapeChange(
changes, this, shape, true
);
shapeChange.apply();
}
}
class Model {
private final ObjectProperty<DrawableShape> selectedShape = new SimpleObjectProperty<>();
public ObjectProperty<DrawableShape> selectedShapeProperty() {
return selectedShape;
}
}
class Ribbon extends ToolBar {
public Ribbon(Model model, UndoManager<ShapeChange> undoManager) {
UndoControls undoControls = new UndoControls(undoManager);
ShapeSelector shapeSelector = new ShapeSelector();
model.selectedShapeProperty().bindBidirectional(
shapeSelector.selectedShapeProperty()
);
getItems().addAll(undoControls.getControls());
getItems().add(createSpacer());
getItems().addAll(shapeSelector.getControls());
}
private Node createSpacer() {
Pane spacer = new Pane();
spacer.setPrefWidth(10);
return spacer;
}
}
class UndoProvider {
private final UndoManager<ShapeChange> undoManager;
public UndoProvider(EventSource<ShapeChange> changes) {
undoManager = UndoManagerFactory.unlimitedHistorySingleChangeUM(
changes,
ShapeChange::invert,
ShapeChange::apply
);
}
public UndoManager<ShapeChange> getUndoManager() {
return undoManager;
}
}
class ShapeChange {
private final EventSource<ShapeChange> changes;
private final DrawingPane drawingPane;
private final Shape shape;
private final boolean adding;
public ShapeChange(EventSource<ShapeChange> changes, DrawingPane drawingPane, Shape shape, boolean adding) {
this.changes = changes;
this.drawingPane = drawingPane;
this.shape = shape;
this.adding = adding;
}
public void apply() {
if (adding) {
drawingPane.getChildren().add(shape);
} else {
drawingPane.getChildren().remove(shape);
}
changes.push(this);
}
public ShapeChange invert() {
return new ShapeChange(
this.changes,
this.drawingPane,
this.shape,
!adding
);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ShapeChange that = (ShapeChange) o;
return adding == that.adding && Objects.equals(changes, that.changes) && Objects.equals(drawingPane, that.drawingPane) && Objects.equals(shape, that.shape);
}
#Override
public int hashCode() {
return Objects.hash(changes, drawingPane, shape, adding);
}
}
enum DrawableShape {
SQUARE, CIRCLE
}
class UndoControls {
private final Button undo = new Button("<");
private final Button redo = new Button(">");
public UndoControls(UndoManager<ShapeChange> undoManager) {
undo.disableProperty().bind(undoManager.undoAvailableProperty().map(x -> !x));
redo.disableProperty().bind(undoManager.redoAvailableProperty().map(x -> !x));
undo.setOnAction(evt -> undoManager.undo());
redo.setOnAction(evt -> undoManager.redo());
}
public List<Node> getControls() {
return List.of(undo, redo);
}
}
class ShapeSelector {
private final ObjectProperty<DrawableShape> selectedShape = new SimpleObjectProperty<>(DrawableShape.SQUARE);
private final RadioButton squareSelector = looksLikeToggleButton(new RadioButton());
private final RadioButton circleSelector = looksLikeToggleButton(new RadioButton());
public ShapeSelector() {
ShapeFactory shapeFactory = new ShapeFactory();
Rectangle square = shapeFactory.createSquare(0, 0, Color.LIGHTGRAY);
Circle circle = shapeFactory.createCircle(0, 0, Color.LIGHTGRAY);
ToggleGroup toggleGroup = new ToggleGroup();
squareSelector.setGraphic(square);
squareSelector.setToggleGroup(toggleGroup);
squareSelector.setSelected(true);
circleSelector.setGraphic(circle);
circleSelector.setToggleGroup(toggleGroup);
Map<Toggle,DrawableShape> shapeMap = Map.of(
squareSelector, DrawableShape.SQUARE,
circleSelector, DrawableShape.CIRCLE
);
toggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) ->
selectedShape.set(
shapeMap.get(newValue)
)
);
}
public ObjectProperty<DrawableShape> selectedShapeProperty() {
return selectedShape;
}
public List<Node> getControls() {
return List.of(squareSelector, circleSelector);
}
private RadioButton looksLikeToggleButton(RadioButton radioButton) {
radioButton.getStyleClass().remove("radio-button");
radioButton.getStyleClass().add("toggle-button");
return radioButton;
}
}
class ShapeFactory {
private static final double BASE_SIZE = 20;
private static final double STROKE_WIDTH = 3;
private static final List<Color> palette = List.of(
Color.LIGHTBLUE,
Color.LIGHTGREEN,
Color.LIGHTCORAL,
Color.LIGHTGOLDENRODYELLOW,
Color.LIGHTPINK,
Color.LIGHTSALMON,
Color.LIGHTSEAGREEN,
Color.LIGHTYELLOW
);
private int colorIdx = 0;
public Rectangle createSquare(double x, double y, Color color) {
Rectangle square = new Rectangle(BASE_SIZE, BASE_SIZE);
square.setFill(color);
square.setStroke(color.darker());
square.setStrokeWidth(STROKE_WIDTH);
square.relocate(x, y);
return square;
}
public Circle createCircle(double x, double y, Color color) {
Circle circle = new Circle(BASE_SIZE / 2);
circle.setFill(color);
circle.setStroke(color.darker());
circle.setStrokeWidth(STROKE_WIDTH);
circle.setCenterX(x);
circle.setCenterY(y);
return circle;
}
public Shape create(DrawableShape drawableShape, double x, double y) {
return switch (drawableShape) {
case SQUARE -> createSquare(x, y, nextColor());
case CIRCLE -> createCircle(x, y, nextColor());
};
}
private Color nextColor() {
Color chosenColor = palette.get(colorIdx);
colorIdx = (colorIdx + 1) % palette.size();
return chosenColor;
}
}
module-info.java
module com.example.shapechanger {
requires javafx.controls;
requires org.fxmisc.undo;
requires reactfx;
exports com.example.shapechanger;
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>ShapeChanger</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ShapeChanger</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>19</version>
</dependency>
<dependency>
<groupId>org.fxmisc.undo</groupId>
<artifactId>undofx</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>19</source>
<target>19</target>
<compilerArgs>--enable-preview</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

i have written a code which shows image slideshow now i want to put a button on it how can i do that?

I have tried this code by setting setComponentZOrder() but it also did not worked please give me some suggestion how can i achieve this goal to make an image slideshow and put a button on it in jframe
import java.awt.Image;
import java.awt.*;
import java.awt.event.ActionListener;
import javafx.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.*;
public class slidemain extends JFrame {
JLabel jl;
JButton b;
Timer tm;
int x = 0;
int w;
int h;
String[] list = {
"C:\\Users\\HARITI\\Desktop\\sat.jpg",
"C:\\Users\\HARITI\\Desktop\\mtab.jpg",
"C:\\Users\\HARITI\\Desktop\\abc.jpg"
};
public slidemain()
{
super("java slide show");
// w = super.getWidth();
// h = super.getHeight();
jl = new JLabel();
b = new JButton();
//b.setVisible(true);
super.setComponentZOrder(jl, 0);
super.setComponentZOrder(b, 1);
jl.setBounds(0, 100, 1350, 650);
setImageSize(2);
tm = new Timer(1500, new ActionListener(){
#Override
public void actionPerformed(java.awt.event.ActionEvent e) {
setImageSize(x);
x += 1;
if (x >= list.length)
{
x = 0;
}
}
});
add(jl);
tm.start();
setLayout(null);
getContentPane().setBackground(Color.decode("#bdb67b"));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void setImageSize(int i) {
ImageIcon icon = new ImageIcon(list[i]);
Image img = icon.getImage();
Image newimg = img.getScaledInstance(jl.getWidth(), jl.getHeight(), Image.SCALE_SMOOTH);
ImageIcon newimc = new ImageIcon(newimg);
jl.setIcon(newimc);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new slidemain();
}
}
This...
super.setComponentZOrder(jl, 0);
super.setComponentZOrder(b, 1);
is going to have no affect if neither of the components have been added to the container yet.
Which brings us to your next problem, you never actually add the button to anything
And event if you did, it wouldn't be displayed, because you're using a null layout
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify.
Maybe have a look at Why is it frowned upon to use a null layout in SWING? for some more details

How to draw on jPanel with JOgl

I use JOGL in Netbeans 8.0.2. I want to draw the classic colored triangle on a panel and also to select number of sides of the geometrical figure (4, 5 sides) using the Netbeans palette controls but I have no idea how.The panel is on the frame. So far my code is :
Class PanelGL:
package panelgl;
import com.jogamp.opengl.*;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.awt.GLJPanel;
import java.awt.Dimension;
import javax.swing.JFrame;
public class PanelGL implements GLEventListener{
public static void main(String[] args) {
final GLProfile profile = GLProfile.get( GLProfile.GL2 );
GLCapabilities capabilities = new GLCapabilities(profile);
final GLJPanel glpanel = new GLJPanel( capabilities );
PanelGL triangle = new PanelGL();
glpanel.addGLEventListener( triangle );
glpanel.setSize( 400, 400 );
final GLFrame frame = new GLFrame ("Colored Triangle");
frame.getContentPane().add( glpanel );
frame.setSize( frame.getContentPane().getPreferredSize());
frame.setVisible( true );
}
#Override
public void init(GLAutoDrawable glad) { }
#Override
public void dispose(GLAutoDrawable glad) { }
#Override
public void display(GLAutoDrawable glad) {
final GL2 gl = glad.getGL().getGL2();
gl.glBegin( GL2.GL_TRIANGLES );
gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
gl.glVertex3f( 0.5f,0.7f,0.0f ); // Top
gl.glColor3f( 0.0f,1.0f,0.0f ); // green
gl.glVertex3f( -0.2f,-0.50f,0.0f ); // Bottom Left
gl.glColor3f( 0.0f,0.0f,1.0f ); // blue
gl.glVertex3f( 0.5f,-0.5f,0.0f ); // Bottom Right
gl.glEnd();
}
#Override
public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3) { }
}
Class GLFrame
public class GLFrame extends javax.swing.JFrame {
public GLFrame(String title) {
this.setTitle(title);
initComponents();
}
private javax.swing.JPanel glPanel;
}
glPanel is add via palette.
I want that the drawing to be on this specifically panel (glPanel).
Create a class that extends GLJPanel instead of GLEventListener. You would still use the GLEventListener internally. After you have compiled the class you can right click it in the Projects window for the pop-up menu to select Tools -> Add To Palette ... to add it to the palette. To Create a property that will be editable just use the normal bean pattern with getter and setter or use Alt-Insert and then select Add Property to add the variable and getter and setter.
eg..
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLJPanel;
import java.awt.Dimension;
public class MyJOGLFigure extends GLJPanel {
public MyJOGLFigure() {
this.setPreferredSize(new Dimension(100,100));
final GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities capabilities = new GLCapabilities(profile);
this.addGLEventListener(new GLEventListener() {
#Override
public void init(GLAutoDrawable glad) {
}
#Override
public void dispose(GLAutoDrawable glad) {
}
#Override
public void display(GLAutoDrawable glad) {
System.out.println("numberOfSides = " + numberOfSides);
final GL2 gl = glad.getGL().getGL2();
gl.glBegin(GL2.GL_TRIANGLES);
gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
gl.glVertex3f(0.5f, 0.7f, 0.0f); // Top
gl.glColor3f(0.0f, 1.0f, 0.0f); // green
gl.glVertex3f(-0.2f, -0.50f, 0.0f); // Bottom Left
gl.glColor3f(0.0f, 0.0f, 1.0f); // blue
gl.glVertex3f(0.5f, -0.5f, 0.0f); // Bottom Right
gl.glEnd();
}
#Override
public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3) {
}
});
}
// Example editable property.
private int numberOfSides = 3;
/**
* Get the value of numberOfSides
*
* #return the value of numberOfSides
*/
public int getNumberOfSides() {
return numberOfSides;
}
/**
* Set the value of numberOfSides
*
* #param numberOfSides new value of numberOfSides
*/
public void setNumberOfSides(int numberOfSides) {
this.numberOfSides = numberOfSides;
}
}
After you have dragged the MyJoglFigure from the palette to the JFrame design, you can find and edit the numberOfSides property. NOTE that I only print it, i didn't actually use it to change the drawing. ( exercise for the reader ? )

Multiple RadioButtons Simulator

I'm trying to make a sort of simple soccer simulator. This is the code I created after watching tutorials and i know its pretty bad. All i want to do is add a value to the team, like 1 for the best team and 10 for the worst, and when i click simulate a pop up would show up telling me which team would win given the teams value. But i cant figure out how to do it.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.TitledBorder;
public class sim extends JPanel {
public sim() {
// JFrame constructor
super(true);
JRadioButton chelsea, arsenal, chelsea2, arsenal2;
this.setLayout(new GridLayout(3,0));
ButtonGroup group = new ButtonGroup();
ButtonGroup group2 = new ButtonGroup();
// takes image and saves it the the variable
Icon a = new ImageIcon(getClass().getResource("a.PNG"));
Icon c = new ImageIcon(getClass().getResource("c.JPG"));
chelsea = new JRadioButton("Chelsea",c);
chelsea.setHorizontalTextPosition(AbstractButton.CENTER);
chelsea.setVerticalTextPosition(AbstractButton.BOTTOM);
arsenal = new JRadioButton("Arsenal",a);
arsenal.setHorizontalTextPosition(AbstractButton.CENTER);
arsenal.setVerticalTextPosition(AbstractButton.BOTTOM);
group.add(chelsea);
group.add(arsenal);
JLabel label = new JLabel("");
TitledBorder titled = new TitledBorder("Team 1");
label.setBorder(titled);
chelsea.setBorder(titled);
arsenal.setBorder(titled);
JButton button = new JButton("Simulate");
button.setHorizontalAlignment(JButton.CENTER);
add(button, BorderLayout.CENTER);
chelsea2 = new JRadioButton("Chelsea",c);
chelsea2.setHorizontalTextPosition(AbstractButton.CENTER);
chelsea2.setVerticalTextPosition(AbstractButton.BOTTOM);
arsenal2 = new JRadioButton("Arsenal",a);
arsenal2.setHorizontalTextPosition(AbstractButton.CENTER);
arsenal2.setVerticalTextPosition(AbstractButton.BOTTOM);
group2.add(chelsea2);
group2.add(arsenal2);
JLabel label2 = new JLabel("");
TitledBorder titled2 = new TitledBorder("Team 2");
label2.setBorder(titled2);
chelsea2.setBorder(titled);
arsenal2.setBorder(titled);
add(label);
add(chelsea);
add(arsenal);
add(button);
add(chelsea2);
add(arsenal2);
HandlerClass handler = new HandlerClass();
chelsea.addActionListener(handler);
}
private class HandlerClass implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//JOptionPane.showMessageDialog(null, String.format("%s", e.getActionCommand()));
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Final");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1920, 1080);
frame.setContentPane(new sim());
frame.setVisible(true);
}
}
Put the ActionListener into the sim class.
public void actionPerformed(ActionEvent e)
{
JButton clicked = (JButton)e.getSource();
if(clicked == button)
{
JOptionPane.showMessageDialog(null, "this team will win");
}
}
You need to decrees the amount of code to just amount needed you dont need to show us all the raidio

Why isn't my JFrame displaying anything from my Jpanel?

I'm working on creating a 3 man's morris board, but nothing is being displayed on the frame. It's empty despite having added my JPanel. Everything is fine if I used board = new JPanel(new GridLayout()); and do the following, but I wouldn't be able to draw the lines that would draw the board. I've looked over it a few times but can't seem to find a problem.
public class Project5 extends JFrame {
public final static int FRAME_WIDTH = 600;
public final static int FRAME_HEIGHT = 600;
private JButton jb[] = new JButton[9];
private Board board = new Board();
Project5(){
for(int i = 0; i<9; i++){
jb[i] = new JButton();
board.add(jb[i]);
}
add(board);
}
public static void main(String[] args) {
JFrame frame = new Project5();
frame.setTitle("Three Man's Morris");
frame.setSize(Project5.FRAME_WIDTH,Project5.FRAME_HEIGHT);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class Board extends JPanel{
public Board(){
super();
setLayout(new GridLayout(3,0,Project5.FRAME_WIDTH,Project5.FRAME_HEIGHT));
}
#Override
public void paintComponents(Graphics g){
super.paintComponents(g);
g.drawLine(0, Project5.FRAME_WIDTH, 0, Project5.FRAME_HEIGHT);
g.drawLine(0, 0, 0, Project5.FRAME_HEIGHT);
g.drawLine(0,Project5.FRAME_WIDTH,0,0);
g.drawLine(0, Project5.FRAME_HEIGHT, Project5.FRAME_WIDTH, Project5.FRAME_HEIGHT);
g.drawLine(Project5.FRAME_WIDTH, 0, 0, Project5.FRAME_HEIGHT);
g.drawLine(Project5.FRAME_WIDTH,0,Project5.FRAME_WIDTH,Project5.FRAME_HEIGHT);
}
}
The problem is in your GridLayout() parameters :
GridLayout(rows,cols,horizontal_gap,vertical_gap)
in your case, both gaps are 600 (FRAME_WIDTH, FRAME_HEIGHT) !
The buttons are displayed, but they are outside the panel, try to lower the gap,
i.e. : setLayout(new GridLayout(3,0,0,0));
You should see the buttons.