Is GC drawing on top of an SWT_AWT Bridged frame possible? - java

I am trying to do something of this sort with no luck.
Composite c = new Composite(shell);
JFrame frame = SWT_AWT.new_Frame(c);
GC gc = new GC(c);
c.fillRectangle(0, 0, 100, 100);
code runs fine but I can't get the rectangle to show on top. I think the frame hides it. Is there a way to put the GC drawings on top?
Thanks,
-Hadi

Apparently, in SWT, transparency is not possible. There are some options available that might lead you to think they're built for this effect but all they do does is either not render say the canvas background or render it using alpha value without rendering the composites bellow it. In other words, SWT doesn't allow you to have see through components.

Related

Dynamically resize images linked to JLabels in a GridLayout layoutmanager

Current implementation layout:
((EDIT: added
Code: ))
private JPanel panelCenter;
private List<BufferedImage> listCreatedImages;
public ChooseCircuitPanel(List<BufferedImage> listCreatedImages) {
this.listCreatedImages = listCreatedImages;
initiate();
}
private void initiate() {
setLayout(new BorderLayout(50, 50));
panelCenter = new JPanel();
LayoutManager theLayout = new GridLayout(0, 3, 0, 0);
panelCenter.setLayout(theLayout);
panelCenter.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for (BufferedImage bufferedImage : listCreatedImages) {
ImageIcon theImage = new ImageIcon(bufferedImage);
JLabel lblForImage = new JLabel(theImage);
lblForImage.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panelCenter.add(lblForImage);
}
this.add(panelCenter, BorderLayout.CENTER);
}
Situation:
We want to display a race circuit here. A circuit should be displayed by placing standards tiles next to each other. It should be possible to resize the window, and with that, the circuit tiles should also resize.
((EDIT: bit more info: The race circuit data is stored on a server and the desktop application has to translate the data to a visual thing, by placing some standard tiles in the right order. ))
((EDIT: we are not allowed to use any external library. It should be doable by only using Java Swing code.))
I thought about placing the images in a JLabel and placing these JLabels in a panel with GridLayout as layout manager.
Using a GridLayout - I thought - it should be rather easy to get to a solution:
the components in the GridLayout (= JLabels) already scale and do exactly what I want.
Now, it would only be a matter of finding a way to resize the images so they fill the JLabels.
As you can see: right now, the images have a fixed size and don't scale at all.
I browsed a bit and saw lots of solutions that boil down to using Graphics2D and super.paintComponent, etc.
But most of these solutions had nothing to do with a GridLayout.
So conclusive question:
Is there an easier solution aside from using Graphics2D, etc. knowing that I use a GridLayout?
If not, I will of course use Graphics2D, etc. but I'm now just exploring my options. :)
((EDIT: SOLVED The tiles now neatly fit on each other. Don't mind the misalignments, that's our fault.))
There are no Swing components that do what you want so you will need to write your own code.
The easiest approach would be to use Darryl's Stretch Icon on your JLabel.
Or another approach is to create your own custom component that dynamically scales the image as it is painted. Something like the Background Panel which has code that allows you to scale or tile an image.
Given the nature of the view, I would recommend abandoning images altogether and instead implement the rendering in an Icon. Presuming you can make an icon scale with the label.

Is it Better to Paint or Use a JLabel

I am working on a Swing application that will have some images in the background. I was wondering which of the following ways are more efficient (or better), or if you had another to suggest:
getGraphics().drawImage(t.getImage().getImage(), i * 16, j * 16, this);
or
JLabel tile = new JLabel(t.getImage());
tile.setBounds(i * 16, j * 16, t.getImage().getIconWidth(), t.getImage().getIconHeight());
add(tile);
Edit:
This is where the stuff will happen:
for (int j = 0; j < 3; j++) {
for (int i = 0; i < 3; i++) {
Tile t = map.getTiles()[j][i];
if (t != null) {
// Draw it somehow.
}
}
}
Regarding:
getGraphics().drawImage(t.getImage().getImage(), i * 16, j * 16, this);
You should never draw with a Graphics object obtained by calling getGraphics() on a component as the Graphics object thus obtained will be short-lived, and your drawing can become unstable. To see what I mean, try using your technique, and then after your GUI has been created, minimize and restore it, and you'll likely see a portion or all of your image has disappeared. Instead you should either draw inside of the JPanel (or other JComponent-derived class)'s paintComponent(...) method using the Graphics object given you.
Also don't read in the image every time you want to draw it as doing this causes an unnecessary slowing of your program. Instead, if the images aren't huge, read them in once at program start up, put them in a BufferedImage or ImageIcon variable (depending on the need), and use them when and where needed in the application.
Regarding:
JLabel tile = new JLabel(t.getImage());
tile.setBounds(i * 16, j * 16, t.getImage().getIconWidth(), t.getImage().getIconHeight());
add(tile);
This is fine except for the setBounds(...) part which suggests that the program is not using layout managers appropriately. Let the JLabel and its ImageIcon set its own preferred size and let the layout managers use this when setting out components and sizing the GUI.
Note that you can give JLabel's layout managers and add components to them just as if they were a JPanel. The main difference is that JLabels are not opaque by default.
Regarding which is better, using a JLabel to hold the image or drawing in the paintComponent(...): often it depends on if the image must resize to fit the component. If so, draw in the JPanel's paintComponent(...). Otherwise use the JLabel.
Edit
Per your comments:
Regarding part two, I am not using a layout manager.
Then your GUI's are at risk of being ugly on different OS's, and are at risk of not being very extensible. The layout managers are one of the most powerful aspects of Swing programming, and if you use them your GUI's will be much easier to code, to update, to enhance, and to work well on other systems.
Regarding part two, what Graphics object am I passing to paintComponent()?
You don't pass any Graphics object into a JPanel's paintComponent(Graphics g). This is a method that is called by the JVM's repaint manager at either your suggestion (by calling repaint()) or the suggestion of the operating system.
Finally, are you saying that it doesn't really matter which of the two options I use?
No, I didn't say that. Please re-read my recommendation just above this edit.
Edit 2
Key Links:
Lesson: Performing Custom Painting: for the nuts and bolts
Painting in AWT and Swing: for the gory details.
Edit 3
For a tile map, I'd use ImageIcons for my tile images, and then would have them displayed within a grid of JLabels. This way, swapping tiles would be as trivial as calling setIcon(nextIcon) on the JLabel of interest.
For example, please see TrashGod and my answers to this question: jlabel images array.
Regarding:
As far as the layout manager, I have a good reason. I've made many GUIs with layout managers, but this one is special ;).
Do so at your own risk, and I'm willing to wager a beer that your reasoning for this is incorrect.
Edit 4
The reason why I am not using a layout manager is because I am trying to make a small RPG game in Swing.
Then the tiles would be best held in a container that uses a GridLayout, and that container could possibly be held in a JScrollPane so that you could scroll in whichever direction. You could then either have your sprites sit in the JLabels (by giving them an appropriate layout), or on top by using a JLayeredPane.
I don't want any comments telling me I can't or I shouldn't because if it is impossible, I'll find out on my own.
We're not here to tell you that you can't do anything, of course, but otherwise you can't stipulate what we should or shouldn't tell you. You've come here asking for our advice, and we have an obligation to tell you what we think would work best. You have a right to follow our advice or not since it's your program, but again, you can't stipulate what we can or can't tell you, other than that you should not tolerate or allow rude or offensive statements (flag the moderators if you see this, and they'll take care of it).
Using JLabel will occupy space in container.
While drawing on container will not occupy container's space.

How to make a jlabel resizable according to the window

I am using netbeans to design a JFrame.
now when i compile and run.It executes and opens a window
now the problem is when i maximixe the window..I want the image or Jlabel to cover the width of the jframe.
SO how can i do it.Plz Help
First stop using visual designer. Stop now. Immediately. Forget that it exists. Visual designers create non-maintainable code. They save 5 minutes at the beginning and cause you to spend hours later.
Now, take a look on any java layouts tutorial. For example this one: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Once you read and understood it go back to your application. Think what layout(s) you need. Design the application. Implement it. If you still have problem that you cannot solve yourself within reasonable time ask more specific question again.
When you understand layouts good enough and want to implement real application with a lot of dialogs take a look on MigLayout.
A JLabel always paints the Icon at it actual size.
If you want dynamic scaling of the image then you need to do custom painting. Basically you would override the paintComponent(..) method of a JComponent with code like:
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
Of course you would need to pass the image as a parameter when you create the class. It also assumes you add the component directly to the content pane which uses a BorderLayout by default.
For fancier or more flexible solutions you could:
Use the Background Panel
Use Stretch Icon on a JLabel

Can you put JFrames inside Full Screen Exclusive Mode?

To be honest, I didn't quite know how to express my question in the title. So if someone has a clearer idea of what i'm trying to ask, then please be so kind as to edit it, for the greater good of mankind.
I have the following code:
public class Main {
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
JFrame frame = new JFrame();
Window window = new Window(frame);
JButton btn = new JButton("Quit");
window.add(btn);
if(gd.isFullScreenSupported())
gd.setFullScreenWindow(window);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.setFullScreenWindow(null);
}
});
}
}
What I want to do is make a library system, illustrated in full screen mode. Inside the full screen mode, there should be simple frame windows with text fields in them and so on... No heavy 2D/3D graphics required here...
My problem is, the quit button is resized to fit the entire screen. I've tried to use setBounds, setSize, etc, on the frame, window and even button... But it doesn't seem to let me be able to center the button in the middle.
So my question: Is it possible to make JFrame application windows inside a JFrame application window which is set to full screen exclusive mode? Or is it only possible to use full screen exclusive mode together with 2D/3D methods like drawing?
Note: The only thing I intend to use full screen mode for is to set it to a black background, and have a Jframe window ontop of this black background in the center of the application. It is to give the illusion that the application is actually a system.
Thank you.
P.S. please note that the quit button was merely for my own testing purposes. It won't be part of the actual system, so my question does not revolve around how to resize this particular quit button.
Fullscreen Exclusive Mode is not meant to have Swing components inside. It is meant as a high performance way to draw graphics in Java (and can benefit as much as possible of underlaying hardware if done right).
What you want to do could be done by using an undecorated JDesktopPane and maximize it over the dimensions of the screen. Then proceed with using a JInternalFrame to have a JFrame like window inside that JDesktopPane.
I've included links to the respective API sections, they should get you started.
I think that what you are after is an MDI Application. If that is what you are after you could take a look here.
Your problem is that you do not use layout manager correctly.
Learn about layout managers - the modules that put and size/resize the visual components on screen. Then decide how do you want your button to look like and then decide which layout manager to use. It will do its job.
You know what i also had the exact same problem and the only thing i know from my experience is that you can use jinternal frame and set its property undecorated to true then add your custom title bar according to your requirement.

Create a rounded JFrame / ContentPane

I'm creating a login window with rounded corners in java. Everything is OK, see pic, but i'm having challenges making the JFrame / ContentPane transparent. There are white areas at each corner (shown by the arrows) that i seem not to be able to remove since i can't set opague to false for the JFrame or ContentPane.
Any ideas of how i can remove these white areas
Since Java 1.3 there's a trick which allows to make partially transparent windows, or windows fading in (I usually use this for my splash screens), or special FX (such as shadows):
Before opening the window, programmatically take a screenshot of the region where your window is going to be (using java.awt.Robot.createScreenCapture())
Set the screenshot as the background of your root container (JPanel with custom paintComponent() routine)
Now you can add all kinds of transparent components, or paint another semitransparent image on top of the background.
Example which creates a window with a semitransparent shadow using this technique:
http://www.eclipsezone.com/eclipse/forums/t17720.html
Not much help to you but Java7 will support transparent and shaped windows: More info here. These are available already in Java 6u10 but not publicly, ie, you need to use an unsupported com.sun... class that might change in future and break your program.
try this. its work :)
yourframe.setBackground(new Color(0, 0, 0, 180));
yourframe.setUndecorated(true);
yourframe.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 80, 80));
}
});
JFrame can not be made transparent as it is a heavyweight component. Only lightweight components such as JWindow can be made transparent.

Categories

Resources