Make JInternal Frame non-moveable - java

I am making an apllication in java swing for practice by using drag and drop components , i am facing a problem, i put inside the JPanel, an JInternal Frame
, it is moveable,
i want to make it un-moveable
,which event is used for it? How can i do it ? i search on the internet but unfortunately unable to find the solution for this.
I have found this on internet but i want to do it with the help of event option in swing.
// Make first internal frame unmovable
JInternalFrame[] frames = frame.desktop.getAllFrames();
JInternalFrame f = frames[0];
BasicInternalFrameUI ui = (BasicInternalFrameUI)f.getUI();
Component north = ui.getNorthPane();
MouseMotionListener[] actions = // there is no option for MouseMotionListener in the event option
(MouseMotionListener[])north.getListeners(MouseMotionListener.class);
for (int i = 0; i < actions.length; i++)
north.removeMouseMotionListener( actions[i] );

DesktopManager is resposible for all operation with internal frames. So you can redefine it using the proxy pattern to make some of your frames non-movable. Here is non-complete example for you (sorry I havn't tested this code, so I'm not sure whether it works).
private static class ProxyDesktopManager implements DesktopManager {
private final DesktopManager delegate;
public ProxyDesktopManager(DesktopManager delegate) {
this.delegate = Objects.requireNonNull(delegate);
}
// Check whether frame is moveable
private boolean checkFrameMovable(JComponent frame) {
if (frame instanceof JInternalFrame) {
// TODO check whether the frame if movable
}
return false;
}
#Override
public void beginDraggingFrame(JComponent f) {
if (checkFrameMovable(f)) {
delegate.beginDraggingFrame(f);
}
}
#Override
public void dragFrame(JComponent f, int newX, int newY) {
if (checkFrameMovable(f)) {
delegate.dragFrame(f, newX, newY);
}
}
#Override
public void endDraggingFrame(JComponent f) {
if (checkFrameMovable(f)) {
delegate.endDraggingFrame(f);
}
}
#Override
public void openFrame(JInternalFrame f) {
delegate.openFrame(f);
}
#Override
public void closeFrame(JInternalFrame f) {
delegate.closeFrame(f);
}
#Override
public void maximizeFrame(JInternalFrame f) {
delegate.maximizeFrame(f);
}
#Override
public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
}
// IMPORTANT: simply delegate all another methods like openFrame or
// resizeFrame
}
Now you can use this proxy class for your JDesktopPane
JDesktopPane desktop = new JDesktopPane();
desktop.setDesktopManager(new ProxyDesktopManager(desktop.getDesktopManager()));

Related

Change the color of multiple cells with one mouse click in Swing

I am using Swing to create a game that has a 10 by 10 grid of cells. The color of each cell can be changed by a mouse click. Here are two classes that work together to accomplish this:
public class Grid extends Battle {
public Grid(String name) {
super();
}
#Override
protected JPanel getCell()
{
JPanel panel = new JPanel();
panel.setBackground(Color.black);
panel.setBorder(BorderFactory.createLineBorder(Color.blue, 1));
panel.setPreferredSize(new Dimension(20, 20));
panel.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e)
{
panel.setBackground(Color.green);
}
});
return panel;
}
}
public abstract class Battle extends JPanel {
public BattleGrid() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JPanel self = new JPanel();
self.setLayout(new GridLayout(0,10));
for (int i = 0; i < 10; i++)
{
for(int j =0; j < 10; j++) {
JPanel panel = getCell();
self.add(panel);
}
}
this.add(self);
}
protected abstract JPanel getCell();
}
The code works for any one particular cell. My question is, how can I change the color of multiple cells in the grid with ONE mouse click? For example, when you click on the grid you change the color of two cells: the one you click on AND the one that is, say, immediately to the right of it? Thank you in advance!
Edit: for those who run into a similar problem - I found super similar solution. Simply increase the dimension of the JPanel being clicked on and return in. For example, the dimension of my JPanel is 20 by 20. So if you want to color 2 cells with one click - the one being clicked and the one to the right - all you have to do is:
panel.setSize(new Dimension(40,20));
You need to start by decoupling the state management from the rest of the code. This should be maintained in some kind of model, which has no concept of the UI, nor should it care, it simply managers the state and makes appropriate decisions about what should be done as that state is changed.
The model would provide an observer pattern implementation, which allow it to generate events when the state is changed, allowing interested parties know when the state has changed, so they can respond to it.
public enum CellState {
EMPTY, SELECTED
}
public class GridModel {
private Set<ChangeListener> listeners;
private CellState[][] grid;
public GridModel() {
listeners = new HashSet<>(25);
grid = new CellState[10][10];
for (int col = 0; col < grid.length; col++) {
for (int row = 0; row < grid[col].length; row++) {
grid[col][row] = CellState.EMPTY;
}
}
}
public void setCellState(CellState state, int x, int y) {
grid[x][y] = state;
}
public CellState getCellStateAt(int x, int y) {
return grid[x][y];
}
public void addChangeListener(ChangeListener listener) {
listeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
listeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
}
Next, I'd create a dedicated Cell component which would be responsible for the management of a single cell. This would provide a visual representation of a cell within the model and coordinate interaction between the user and the model.
public class Cell extends JPanel {
private GridModel model;
public Cell(GridModel model, int x, int y) {
this.model = model;
setBackground(Color.black);
setBorder(BorderFactory.createLineBorder(Color.blue, 1));
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
getModel().setCellState(CellState.SELECTED, x, y);
}
});
model.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
switch (getModel().getCellStateAt(x, y)) {
case SELECTED:
setBackground(Color.BLUE);
break;
case EMPTY:
setBackground(Color.BLACK);
break;
}
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(20, 20);
}
public GridModel getModel() {
return model;
}
}
And then, your Grid class would create an instance of this Cell as required
public class Grid extends Battle {
private GridModel model;
public Grid(String name, GridModel model) {
super();
this.model = model;
}
public GridModel getModel() {
return model;
}
#Override
protected JPanel getCell(int x, int y) {
return new Cell(getModel(), x, y);
}
}
This is only a proof of concept and your requirements may be more complex then I've generally presented, by the basic concept of decoupled state manager (model) and notification system (observer pattern) and the key elements to your solution.
This moves you closer to a Model-View-Controller paradigm, allow appropriate separation of various responsibilities with the system

Close additional window (PApplet)

How to close new frame without exiting whole application?
What is easiest way to do it by clicking X button.
Thanks in advance.
ControlFrame cf;
void setup()
{
cf = new ControlFrame(this,500,500, "cf name");
}
class ControlFrame extends PApplet
{
int w,h;
PApplet parent;
public ControlFrame(PApplet _parent, int _w, int _h, String _name)
{
super();
parent=_parent; w=_w; h=_h;
PApplet.runSketch(new String[]{this.getClass().getName()},this);
}
public void settings()
{ size(w,h); }
}
Note: Your question doesn't really have anything to do with ControlP5.
Step 1: Get a reference to the native window. How you do this depends on the renderer you're using. If you're using the default renderer, it looks like this:
Frame frame = ( (SmoothCanvas) ((PSurfaceAWT)surface).getNative()).getFrame();
Step 2: You can then call dispose() on that Frame to hide it without quititng the entire application.
frame.dispose();
Putting it all together, it looks like this:
import java.awt.Frame;
import processing.awt.PSurfaceAWT;
import processing.awt.PSurfaceAWT.SmoothCanvas;
ControlFrame cf;
void setup()
{
cf = new ControlFrame(this, 500, 500, "cf name");
}
class ControlFrame extends PApplet
{
int w, h;
PApplet parent;
public ControlFrame(PApplet _parent, int _w, int _h, String _name)
{
super();
parent=_parent;
w=_w;
h=_h;
PApplet.runSketch(new String[]{this.getClass().getName()}, this);
}
public void settings()
{
size(w, h);
}
public void draw(){
//needed for mousePressed
println(millis());
}
public void mousePressed(){
Frame frame = ( (SmoothCanvas) ((PSurfaceAWT)surface).getNative()).getFrame();
frame.dispose();
}
}
Step 3: Note that your second sketch will continue running, so you might also want to call noLoop() to prevent unnecessary computation.

How to create interactive graphic with Vaadin?

I want to develop a simple interactive game (like arcanoid). I already have implemented a menu and different views, and now I need to develop the actually game (draw flying ball, some movable platform) and I don't know how to do this. I need something like canvas where I can draw my graphic each frame.
I have tryed to implement this with Canvas and Timer. But it doesn't want update graphic itself, but only when user clicks on screen or similar. Also I saw com.google.gwt.canvas.client.Canvas, but I cannot understand how to use it in Vaadin application.
So my question is next: is it possible to draw some graphic each frame with high framerate in any way? If possible, how can I do this?
P.S. I use the Vaadin 7.3.3.
ADDED LATER:
Here is a link to my educational project with implementation below.
I'll be glad if it helps someone.
ORIGINAL ANSWER:
Well... I found the solution myself. First of all, I have created my own widget - "client side" component (according to this article).
Client side part:
public class GWTMyCanvasWidget extends Composite {
public static final String CLASSNAME = "mycomponent";
private static final int FRAMERATE = 30;
public GWTMyCanvasWidget() {
canvas = Canvas.createIfSupported();
initWidget(canvas);
setStyleName(CLASSNAME);
}
Connector:
#Connect(MyCanvas.class)
public class MyCanvasConnector extends AbstractComponentConnector {
#Override
public Widget getWidget() {
return (GWTMyCanvasWidget) super.getWidget();
}
#Override
protected Widget createWidget() {
return GWT.create(GWTMyCanvasWidget.class);
}
}
Server side part:
public class MyCanvas extends AbstractComponent {
#Override
public MyCanvasState getState() {
return (MyCanvasState) super.getState();
}
}
Then I just add MyCanvas component on my View:
private void createCanvas() {
MyCanvas canvas = new MyCanvas();
addComponent(canvas);
canvas.setSizeFull();
}
And now I can draw anything on Canvas (on client side in GWTMyCanvasWidget) with great performance =). Example:
public class GWTMyCanvasWidget extends Composite {
public static final String CLASSNAME = "mycomponent";
private static final int FRAMERATE = 30;
private Canvas canvas;
private Platform platform;
private int textX;
public GWTMyCanvasWidget() {
canvas = Canvas.createIfSupported();
canvas.addMouseMoveHandler(new MouseMoveHandler() {
#Override
public void onMouseMove(MouseMoveEvent event) {
if (platform != null) {
platform.setCenterX(event.getX());
}
}
});
initWidget(canvas);
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent resizeEvent) {
resizeCanvas(resizeEvent.getWidth(), resizeEvent.getHeight());
}
});
initGameTimer();
resizeCanvas(Window.getClientWidth(), Window.getClientHeight());
setStyleName(CLASSNAME);
platform = createPlatform();
}
private void resizeCanvas(int width, int height) {
canvas.setWidth(width + "px");
canvas.setCoordinateSpaceWidth(width);
canvas.setHeight(height + "px");
canvas.setCoordinateSpaceHeight(height);
}
private void initGameTimer() {
Timer timer = new Timer() {
#Override
public void run() {
drawCanvas();
}
};
timer.scheduleRepeating(1000 / FRAMERATE);
}
private void drawCanvas() {
canvas.getContext2d().clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
drawPlatform();
}
private Platform createPlatform() {
Platform platform = new Platform();
platform.setY(Window.getClientHeight());
return platform;
}
private void drawPlatform() {
canvas.getContext2d().fillRect(platform.getCenterX() - platform.getWidth() / 2, platform.getY() - 100, platform.getWidth(), platform.getHeight());
}
}

JME: How to get the complete screen in WHITE without buttons, etc etc

Please have a look at the following code
First, Please note I am a 100% newbie to Java Mobile.
In here, I am making the light on and vibrate on when user click the button. However, I really wanted to create a SOS application which turn the whole screen into white, and go to black, like that, in the thread. I guess I didn't achieve that by this app because even the lights are on, the buttons are still there. I tried to turn the "Form" color to "white" but it seems like JME has no "Color" class.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Midlet extends MIDlet{
private Form f;
private Display d;
private Command start,stop;
private Thread t;
public Midlet()
{
t = new Thread(new TurnLightOn());
}
public void startApp()
{
f = new Form("Back Light On");
d = Display.getDisplay(this);
d.setCurrent(f);
start = new Command("Turn On",Command.OK,0);
stop = new Command("Turn Off",Command.OK,1);
f.addCommand(start);
f.setCommandListener(new Action());
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional)
{
this.notifyDestroyed();
}
private class Action implements CommandListener
{
public void commandAction(Command c, Displayable dis)
{
f.append("Light is Turnning On");
t.start();
}
}
private class ActionOff implements CommandListener
{
public void commandAction(Command c, Displayable dis)
{
}
}
private class TurnLightOn implements Runnable
{
public void run()
{
f.append("Working");
for(int i=0;i<100;i++)
{
try
{
d.flashBacklight(200);
d.vibrate(200);
Thread.sleep(1000);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
}
Use the javax.microedition.lcdui.Canvas instead of Form. This example can get you started
public void startApp()
{
f = new Form("Back Light On");
d = Display.getDisplay(this);
start = new Command("Turn On",Command.OK,0);
stop = new Command("Turn Off",Command.OK,1);
f.addCommand(start);
f.setCommandListener(new Action());
myCanvas = new MyCanvas();
d.setCurrent(myCanvas);
myCanvas.repaint();
}
Now create a canvas and implement paint method like this:
class MyCanvas extends Canvas {
public void paint(Graphics g) {
// create a 20x20 black square in the center
// clear the screen first
g.setColor(0xffffff);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0xffffff); // make sure it is white color
// draw the square, <b>changed to rely on instance variables</b>
<b>g.fillRect(x, y, getWidth(), getHeight());</b>
}
}

Boolean Value Change Listener Java

I need a listener that will constantly check if a static boolean value has been changed so that I can repaint a component on a frame. Can someone please help me I really don't know much about listeners and haven't worked with them much? Help will be greatly appreciated.
edit(more clarity): I have two separate classes in which on class is the "main frame" the second class is an extension of JLabel and implements MouseListner for a "clickable photo". The "main frame" creates instances of the photo and when the photo is clicked the "main frame" is supposed to paint on the panel a description of the photo. This is "main frame"
MenuBar menuBar;
static AnnotationVisual a;
Picture pic;
Picture pic2;
GalleryScreen(int rows, int columns){
this.setBorder(BorderFactory.createEmptyBorder(500,500,0,0));
pic = new Picture("pic1", "Z:/My Documents/Downloads/Ball.jpg", new Coordinate(0,0));
pic2 = new Picture("pic2", "Z:/My Documents/Downloads/hoop.jpg" , new Coordinate(1,0));
this.add(pic);
this.add(pic2);
a = new AnnotationVisual();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(a.shouldAnnotate()){
FontMetrics size= g.getFontMetrics();
if(getWidth()>=(a.dispX()+size.stringWidth(a.annotationText()))){
g.setColor(Color.white);
g.fillRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15);
g.setColor(Color.black);
g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15);
g.drawString(a.annotationText(), a.dispX(), a.dispY());
}else{
String sub="";
int letters=0;
g.setColor(Color.white);
g.fillRect(a.dispX()-3,a.dispY()-12,getWidth(),15);
g.setColor(Color.black);
for(int i=0;i<a.annotationText().length();i++){
if(a.dispX()+letters+16<=getWidth()){
sub+=a.annotationText().substring(i,i+1);
letters=size.stringWidth(sub);
}else{
sub=sub+"...";
i=a.annotationText().length();
}
}
g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(sub)+3,15);
g.drawString(sub,a.dispX(),a.dispY());
}
}
}
public static AnnotationVisual getA()
{
return a;
}
This is "clickable photo"
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.*;
import javax.swing.*;
public class Picture extends JLabel implements MouseListener
{
String myAnnotation;
String filePath;
Coordinate imageCoord;
private boolean wasDoubleClick;
private Timer timer;
EditAnnotation newEdit;
AnnotationVisual newVisual;
public Picture(String annotation, String filePath, Coordinate coord)
{
super(new ImageIcon(filePath));
this.addMouseListener(this);
myAnnotation=annotation;
this.filePath = filePath;
imageCoord = coord;
newEdit = new EditAnnotation(annotation);
newVisual = new AnnotationVisual();
}
public Picture(String filePath)
{
super(new ImageIcon(filePath));
this.addMouseListener(this);
this.filePath = filePath;
newEdit = new EditAnnotation();
newVisual = new AnnotationVisual();
}
public String getAnnotation()
{
return myAnnotation;
}
public AnnotationVisual getAnnotationVisual()
{
return newVisual;
}
public void setAnnotation(String annotation)
{
myAnnotation=annotation;
}
public Coordinate getCoordinate()
{
return imageCoord;
}
public void setCoordinate(Coordinate coord)
{
imageCoord = coord;
}
public Dimension getSize()
{
return new Dimension(super.getIcon().getIconWidth(), super.getIcon().getIconHeight());
}
public void mouseClicked(MouseEvent e)
{
final int scrLocX = (int)e.getLocationOnScreen().getX();
final int scrLocY = (int)e.getLocationOnScreen().getY();
if (e.getClickCount() == 2)
{
wasDoubleClick = true;
}
else if(e.getClickCount() == 1)
{
Integer timerinterval = (Integer) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
timer = new Timer(timerinterval.intValue(), new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (wasDoubleClick)
{
GalleryScreen.getA().deleteAnnotation();
myAnnotation = newEdit.getAnnotation();
newEdit.show(myAnnotation);
wasDoubleClick = false;
}
else
{
GalleryScreen.getA().deleteAnnotation();
GalleryScreen.getA().showAnnotation(scrLocX, scrLocY , myAnnotation);
}
}
});
timer.setRepeats(false);
timer.start();
}
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
}
AnnotationVisual is the thing that supposed to pop up when single clicked
You're probably better off making the boolean private, and only allowing it to be changed through a setter method. The setter method, when called, should then repaint the component.
The point of listeners is to invert the logic. You don't constantly check if a value is changed. You notify the listener when you change the value.
So, instead of Foo.bar = 5, you invoke Foo.setBar(5), where in addition to the assignment, you call barListener.valueChanged(value)
As a sidenote - avoid storing state in static variables.
You don't set a listener on a field in Java, you set it on a property. While properties (according to the JavaBeans spec) can be fields, they're usually done as pairs of methods (one getter, one setter; the latter being not needed for read-only fields) as that lets you hook extra logic in to be called when the property is accessed. Such as firing a listener callback to say that the value has changed. (You could use a thread to monitor for that sort of thing, but that's really nasty and error-prone. Wasteful too.)
One thing to be aware of though: you don't know what thread the value will have been modified from. Take care when invoking back into Swing…

Categories

Resources