I created a simple Java GUI word game.
It starts of with a head, and the user tries to guess the word. If it is right, the system prints out correct. If it is wrong, it will print out "wrong" and draw a body. The top text box is the hidden word (not really hidden) and the bottom is where you insert your guess.
What is wrong with this program is, the body is not painted after the user guess the wrong word.
The first class:
package hangman;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class NewClass extends JPanel {
int lineA, lineB, lineC, LineD;
int guess;
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.ORANGE);
//head
g.drawOval(110, 10, 25, 25);
g.drawLine(lineA, lineB, lineC, LineD);// (ideal) 125, 40, 120, 100
}
public void newPaint(int a, int b, int c, int d) {
lineA = a;
lineB = b;
lineC = c;
LineD = d;
super.revalidate();
}
}
The second class:
package hangman;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class NewClass1 extends JFrame {
private JTextField answerBox, hiddenAnswer;
NewClass nc = new NewClass();
public NewClass1() {
hiddenAnswer = new JTextField();
hiddenAnswer.setText("hat");// this is the word for the hangman
answerBox = new JTextField("put you answer in here");
answerBox.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (event.getActionCommand().equals(hiddenAnswer.getText())) {
System.out.println("you got it right");
} else {
System.out.println("sorry you got it wrong");
nc.newPaint(125, 120, 40, 100);
}
}
});
add(BorderLayout.NORTH, hiddenAnswer);
add(BorderLayout.SOUTH, answerBox);
}
}
entry point
NewClass1 ncc = new NewClass1();
NewClass nc = new NewClass();
ncc.add(BorderLayout.CENTER,nc);
ncc.setVisible(true);
ncc.setSize(300,300);
ncc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Use your newPaint API in the event, instead of directly setting the fields of NewClass.
if (event.getActionCommand().equals(hiddenAnswer.getText()))
{
System.out.println("you got it right");
}
else
{
System.out.println("sorry you got it wrong");
nc.newPaint(125, 120, 40, 100);
}
Edit: In the NewClass1, replace the repaint() with revalidate(). Here's the reference.
Edit2: In your case, it is best that you don't create the NewClass panel outside of NewClass1. In the NewClass1 constructor you can do this:
nc = new NewClass();
add(BorderLayout.CENTER, nc);
before you add the hiddenAnswer, and then you can remove the NewClass from the entry point.
The thing is, you weren't working on the instance of NewClass that you've created in the entry point, you were working with a random new NewClass.
Related
I am stuck with a very unusual situation. I have a class "ScreenSizeSelector" which has a method 'getSelectedScreenSize'. The method's work is to create a UI, user drags the UI and method return back size of window.
Now I am calling the method of class in following ways:
A simple class (non GUI)
On the button click from a JFrame
In the first case, it is working perfectly fine (i.e. size selector window opens, user drags it, resize it and it is giving back window coordinates) but in second case, window opens but in disabled mode, user is not able to perform any operation on the window, not even able to close the window.
Here is the code I am using
ScreenSizeSelector class :
package screenrecorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
class ScreenSizeSelector {
private JFrame sizeSelectorWindow;
private JButton btnOk;
private Border emptyBorder;
private Rectangle screenArea = null;
private static Object lock = new Object();
public Rectangle getSelectedScreenSize(){
screenSizeSelectorUI();
Thread t = new Thread() {
public void run() {
synchronized(lock) {
while (sizeSelectorWindow.isVisible())
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return screenArea;
}
public void screenSizeSelectorUI() {
emptyBorder = BorderFactory.createEmptyBorder();
sizeSelectorWindow = new JFrame("Select screen area");
btnOk = new JButton("Start");
sizeSelectorWindow.setUndecorated(true);
sizeSelectorWindow.getRootPane().setWindowDecorationStyle(3);
sizeSelectorWindow.setBackground( new Color(0, 0, 0, 0) );
sizeSelectorWindow.setSize(400,400);
sizeSelectorWindow.addWindowListener(new WindowEventHandler());
sizeSelectorWindow.setAlwaysOnTop(true);
sizeSelectorWindow.setLocationRelativeTo(null);
btnOk.setToolTipText("Click this button after deciding the screen area");
btnOk.addActionListener(new ButtonEventHandler());
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.setBackground(new Color(0,0,0,0));
buttonPanel.add(btnOk);
sizeSelectorWindow.add(buttonPanel,BorderLayout.SOUTH);
sizeSelectorWindow.setVisible(true);
sizeSelectorWindow.setEnabled(true);
}
class ButtonEventHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int x = (int)(sizeSelectorWindow.getBounds().getX());
int y = (int) (sizeSelectorWindow.getBounds().getY());
int width = sizeSelectorWindow.getWidth();
int height = sizeSelectorWindow.getHeight();
screenArea = new Rectangle(x,y,width,height);
sizeSelectorWindow.dispatchEvent(new WindowEvent(sizeSelectorWindow, WindowEvent.WINDOW_CLOSING));
}
}
class WindowEventHandler implements WindowListener{
#Override
public void windowOpened(WindowEvent e) {
}
#Override
public void windowClosing(WindowEvent e) {
synchronized (lock) {
sizeSelectorWindow.setVisible(false);
lock.notify();
}
}
#Override
public void windowClosed(WindowEvent e) {
}
#Override
public void windowIconified(WindowEvent e) {
sizeSelectorWindow.setState(JFrame.NORMAL);
Toolkit.getDefaultToolkit().beep();
}
#Override
public void windowDeiconified(WindowEvent e) {}
#Override
public void windowActivated(WindowEvent e) {}
#Override
public void windowDeactivated(WindowEvent e) {}
}
}
Test1 class :
package screenrecorder;
import java.awt.Rectangle;
public class Test1{
public static void main(String[] args){
System.out.println(new ScreenSizeSelector().getSelectedScreenSize());
}
}
Test2 class :
package screenrecorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Test2 extends JFrame{
public Test2(){
JButton btn = new JButton("Click ME");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(new ScreenSizeSelector().getSelectedScreenSize());
}
});
getContentPane().add(btn);
setSize(100,100);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
new Test2();
}
}
Any help is appreciated.
when you click the button, the action listener waits for the getSelectedScreenSize() function to return. and the getSelectedScreenSize() function is waiting for the second window created by screenSelectorUI() to be invisible. screenSelectorUI() does create a second window, but you set the color like this:
sizeSelectorWindow.setBackground( new Color(0, 0, 0, 0) );
if you look at the color constructor javadocs:
public Color(int r,
int g,
int b,
int a)
Creates an sRGB color with the specified red, green, blue, and alpha values in the range (0 - 255).
Parameters:
r - the red component
g - the green component
b - the blue component
a - the alpha component
you set the alpha value to 0, making it completely invisible. (alpha value is transparency) also, this second window is undecorated and does not exit on close, so you don't even know it's there at all.
what I don't get is how test1 worked at all.
side note: when I try test 1 on mac it only shows the button and all I can do is click it. the button will disappear, but the application will still be running.
This is basically a total guess, but a lot of the swing components make requests to the operating system, not commands. sort of like saying, "hey can I please be resized to 400, 400?" the OS doesn't technically have to do what you say. and I was reading How does Java handle multithreading? which says that multithreading really depends on the OS. I have a feeling it just messes up somewhere when screenSelectorUI() is called by itself, but somehow gets it right when it's inside the thread of some button.
importing libraries
public class Countdown1 extends Applet implements Runnable {
// getting user input
String input = JOptionPane.showInputDialog("Enter seconds: ");
// converting string to integer
int counter = Integer.parseInt(input);
Thread countdown;
public void start() {
countdown = new Thread(this);
countdown.start();
}
// executed by thread
public void run() {
Timer timer;
timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
public void actionPerformed(ActionEvent evt) {
if (counter > 0) {
counter--;
// repainting each second
repaint();
}
}
});
// timer started
timer.start();
}
public void paint(Graphics g) {
//painting text and time
g.setFont(new Font("Times New Roman", Font.BOLD, 35));
g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
setBackground(Color.orange);
setForeground(Color.magenta);
// change background to cyan when timer reaches 0
if (counter == 0) {
setBackground(Color.cyan);
}
}
}
The problem isn't your Timer (although I do question the need to start it within a separate thread), the problem is with overriding paint.
Top level containers like Applet are not double buffered, meaning that the each paint action tends to be sent to the underlying Graphics device desperately.
Now you can over come this by employee some double buffering process OR you could...
Extend from JApplet instead
Create a custom component extending from something like JPanel and override it's paintComponent method instead, moving your custom painting to this method
Add this component to the applet instead.
It should solve the immediate issue...
You should also avoid calling setForeground or setBackground from within any paint method. In fact, you should avoid calling any method that might call repaint from within any paint method...
Take a look at Performing Custom Painting
I'm pretty sure that String input = JOptionPane.showInputDialog("Enter seconds: "); this is a bad idea. Instead, you should provide some kind of control or option within the UI to change this value...
Crude example
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Countdown1 extends JApplet {
#Override
public void init() {
add(new CounterPane());
}
public class CounterPane extends JPanel {
String input = JOptionPane.showInputDialog("Enter seconds: ");
int counter = Integer.parseInt(input);
public CounterPane() {
Timer timer;
timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
public void actionPerformed(ActionEvent evt) {
System.out.println(counter);
if (counter > 0) {
counter--;
setBackground(Color.orange);
setForeground(Color.magenta);
if (counter <= 0) {
setBackground(Color.cyan);
}
repaint();
}
}
});
timer.start();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Times New Roman", Font.BOLD, 35));
g.setColor(getForeground());
g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
}
}
}
I'm trying to make a code that will move a red ball with JButtons (and later add keybinders). There are no problems when I compile and when I run I see the ball but the JButtons won't affect him. I think the problem might be that the ball is drawed only once and then is called again and again without being drawed in the new position but I don't know how to fix that.
1) does anybody know how I can fix that?
2) is there a way to change the shape of a JPanel to a ball? (that would probably be a simpler way to move him)
package il.co.atlantis;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class KeyBinders implements ActionListener {
boolean right=true, left=false, up=false, down=false, inGame=true;
JPanel backgroundPanel, bannerPanel, scorePanel, applePanel;
JLabel currentScoreLabel, highestScoreLabel;
JButton upButton, downButton, rightButton, leftButton;
long millis =System.currentTimeMillis(), millisn =System.currentTimeMillis();
public static final int WID = 10, HEI = 10;
public static int x1 = 100, y1 = 100;
public class MyGraphics extends JComponent {
private static final long serialVersionUID = 1L;
MyGraphics() {
setPreferredSize(new Dimension(700, 500));
}
public void moveRight(){
++x1;
}
public void moveLeft(){
--x1;
}
public void moveUp(){
--y1;
}
public void moveDown(){
++y1;
}
public void paintComponent(Graphics g){
super.paintComponents(g);
g.setColor(Color.red);
g.fillOval(x1, y1, WID, HEI);
}
}
public JPanel CreateContentPane (){
JPanel totalGUI = new JPanel();
totalGUI.setLayout(null);
backgroundPanel = new JPanel();
backgroundPanel.setBackground(Color.black);
backgroundPanel.setLocation(100, 10);
backgroundPanel.setSize(700, 500);
totalGUI.add(backgroundPanel);
upButton = new JButton("up");
upButton.setLocation(0,0);
upButton.setSize(50,50);
totalGUI.add(upButton);
downButton = new JButton ("down");
downButton.setLocation(0,50);
downButton.setSize(50,50);
totalGUI.add(downButton);
rightButton = new JButton("right");
rightButton.setLocation(0,100);
rightButton.setSize(50,50);
totalGUI.add(rightButton);
leftButton = new JButton("left");
leftButton.setLocation(0,150);
leftButton.setSize(50,50);
totalGUI.add(leftButton);
MyGraphics tr = new MyGraphics();
tr.setLocation(100, 100);
backgroundPanel.add(tr);
return totalGUI;
}
public void ActionPerformed(ActionEvent h){
if(h.getSource() == upButton) {
--y1;
}
else if(h.getSource() == downButton){
++y1;
}
else if(h.getSource() == leftButton){
--x1;
}
else if(h.getSource() == rightButton){
++x1;
}
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JButton Scores! [=]");
//Create and set up the content pane.
KeyBinders demo = new KeyBinders();
frame.setContentPane(demo.CreateContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(280, 190);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public KeyBinders() {
// TODO Auto-generated constructor stub
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
When you invoke action event, actionPerformed() function gets called, as you did. You have change the drawing position too. you need to call Component.repaint() which tells Swing t hat the entire component, whichever one you specified to be repainted , must be updated . So add this function calling in your code. For example:
public void ActionPerformed(ActionEvent h){
if(h.getSource() == upButton) {
--y1;
}
else if(h.getSource() == downButton){
++y1;
}
else if(h.getSource() == leftButton){
--x1;
}
else if(h.getSource() == rightButton){
++x1;
}
repaint();
}
Check the tutorial: Performing Custom Painting.
There's a method called repaint() you should familiarize yourself with.
When called on a component (such as a JFrame) it'll repaint all the components within. Naturally you need to call it if you want your changes to become visible on the screen.
As for custom painting, you shouldn't use a Component at all, rather use the Graphics.fillRect/fillOval etc. methods to just draw what you want.
See here for the custom painting tutorial.
Actually, i have already ask this question in here. But, i'm making mistake. I haven't already get the solution.
First, at the question before, i can get Rectangle with
Rectangle rectangle = textArea.modelToView( textArea.getCaretPostion() );
I'm also get X and Y position.
I'm creating a editor that can add new Text Area each i press Enter key. XY position with code above always give same return in every Text Area. Look my code.
import java.awt.Container;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
public class forquestion extends JFrame {
Container textAreaBox;
LinkedList<JTextComponent> textArea;
int nameTA;
public forquestion() {
int nameTA = 0;
textArea = new LinkedList<>();
textAreaBox = Box.createVerticalBox();
textAreaBox.add(Box.createVerticalGlue());
addLine();
this.add(textAreaBox);
this.setVisible(true);
}
public static void main(String[] args) {
forquestion app = new forquestion();
app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
public void addLine () {
JTextComponent temp_ta = createTextComponent();
textArea.add(temp_ta);
textAreaBox.add(textArea.getLast());
textAreaBox.add(Box.createVerticalGlue());
}
protected JTextComponent createTextComponent() {
JTextArea ta = new JTextArea("test");
/*if (count%2==0)
ta.setForeground(Color.red);
else
ta.setForeground(Color.GREEN);*/
ta.setFont(new Font("Courier New",Font.PLAIN,16));
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
ta.setName(Integer.toString(nameTA));
nameTA+=1;
basicKey("ENTER", enter, ta);
ta.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent ev) {
try {
taMousePressed(ev);
} catch (BadLocationException ex) {
Logger.getLogger(forquestion.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
return ta;
}
public void basicKey(String s, Action a, JTextArea ta) {
ta.getInputMap().put(KeyStroke.getKeyStroke(s), s);
ta.getActionMap().put(s, a);
}
Action enter = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
addLine();
}
};
private void taMousePressed(java.awt.event.MouseEvent ev) throws BadLocationException {
int now_focus = Integer.parseInt(ev.getComponent().getName());
int _caret;
_caret = textArea.get(now_focus).getCaretPosition();
Rectangle rectangle = textArea.get(now_focus).modelToView(_caret);
double x = rectangle.getX();
//int xc = textArea.get(now_focus).getLocation().x;
double y = rectangle.getY();
//int yc = textArea.get(now_focus).getLocation().y;
//double h = rectangle.getHeight();
//double w = rectangle.getWidth();
System.out.println(x);
System.out.println(y);
//System.out.println(xc);
//System.out.println(yc);
//System.out.println(h);
//System.out.println(w);
System.out.println("");
}
}
My code will print XY position each time you press a Text Area. But, the display always same in every text area. (Try to make many Text Area and give some text) Btw, it just simple code. You need change the window frame size for update the new text area after you press enter key..hahaha.
So, my question is: How can i get the XY position of caret (text cursor) in any Text Area. I want to display JPopmenu there. :)
I hope this question clear for you. Thx before.
The Rectangle reported back is relative to the text area, where it's 0x0 position is the top, left corner of the component.
If you use something like...
popup.show(textArea.get(now_focus), rectangle.x, rectangle.y + rectangle.height);
Where popup is a JPopupMenu, it will make the required translations to the screen itself.
Now. Having said that. Personally, I would prefer to use the popup API support provided by Swing. This is going to mean needing to create a custom component that extends from JTextArea to achieve it...
public class MyPopupTextArea extends JTextArea {
/*...*/
public Point getPopupLocation(MouseEvent evt) {
Rectangle rectangle = textArea.get(now_focus).modelToView(_caret);
Point p = rectangle.getLoction();
p.y += rectangle.height;
return p;
}
}
Then, based on your needs, you can use setComponentPopup to provide a shared instance of the JPopupMenu or, if required, create a custom JPopupMenu for each instance of the custom editor and use setComponentPopup as you see fit...no messing about with mouse listeners ;)
I am playing with the JUNG library and I want to create a graph, whose nodes are some gui(jframe presumably) items.
I want each of the nodes to have a few buttons, one text field, menu, etc.
And my question is: is this possible?
If yes, I have two other questions:
1. How should I approach it(I am new to Java and I am not familiar with the best practices )
2. What interface should I use(I am looking at .visualisation.decorators.* currenlty).
Thank you in advance.
OK, eventually I succeeded creating a graph of JPanels and JFrames. I will continue with JPanels. And here is the result:
But now I face some other problems:
The frames can be moved, but only if they are picked at the upper left corner. How can I make the whole JPanel area pickable?
I need the JPanels to be accessible, e.g. I should be able to press the button, write some text in a textbox(this is not implemented yet) and probably resize the JPanel. Currently the JPanels are "inactive/no focus" for some reason. I tried the enable method, no success. Tried some "focus" methods, again failed.
Any suggestions on the above two questions?
Here is how my code looks like:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.Point2D;
import javax.swing.BorderFactory;
import javax.swing.CellRendererPane;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.picking.PickedState;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;
public class GraphPanel extends Container
{
static final long serialVersionUID = 420001L;
DirectedSparseGraph<Number, Number> graph = null;
VisualizationViewer<Number, Number> vv = null;
PickedState<Number> pickedState = null;
public GraphPanel(Number[][] nodes_list)
{
try
{
graph = new DirectedSparseGraph<Number, Number>();
construct_graph(nodes_list);
vv = new VisualizationViewer<Number, Number>
(new CircleLayout<Number, Number>(graph), new Dimension(400, 400));
vv.getRenderer().setVertexRenderer(new MyRenderer());
// The vertex pick listener
pickedState = vv.getPickedVertexState();
pickedState.addItemListener(new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
Object subject = e.getItem();
if (subject instanceof Number)
{
Number vertex = (Number) subject;
if (pickedState.isPicked(vertex))
{
System.out.println("Vertex " + vertex + " is now selected");
}
else
{
System.out.println("Vertex " + vertex + " no longer selected");
}
}
}
});
// The following code adds capability for mouse picking of
// vertices/edges. Vertices can even be moved!
final DefaultModalGraphMouse<Number, Number> graphMouse = new DefaultModalGraphMouse<Number, Number>();
vv.setGraphMouse(graphMouse);
graphMouse.setMode(ModalGraphMouse.Mode.PICKING);
}
catch (Exception e)
{
System.err.println("Failed to construct graph!\n");
System.err.println("Caught Exception: " + e.getMessage());
}
}
/*Attach the graph panel/container to a specified frame*/
public void attach_to_frame(JFrame frame)
{
frame.setContentPane(vv);
}
/*This one should be reimplemented*/
private void construct_graph(Number[][] nodes_list)
{
int i = 0;
/*add the nodes*/
for(i=0; i<nodes_list.length; i++)
{
graph.addVertex(i);
graph.addEdge(nodes_list[i][0], nodes_list[i][1], nodes_list[i][2]);
}
}
/*re-implement the render functionality to work with internal frames(JInternalFrame)*/
static class MyRenderer extends JPanel implements Renderer.Vertex<Number, Number>
{
static final long serialVersionUID = 420000L;
#Override
public void paintVertex(RenderContext<Number, Number> rc,
Layout<Number, Number> layout, Number vertex)
{
try
{
GraphicsDecorator graphicsContext = rc.getGraphicsContext();
Point2D center = layout.transform(vertex);
Dimension size = new Dimension(100, 80);
System.out.printf("Vertex[%d] X = %d Y = %d: Running paintVertex()\n", vertex, (int)center.getX(), (int)center.getY());
JPanel sv = new JPanel();
sv.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
sv.setBackground(Color.GREEN);
sv.setPreferredSize(size);
sv.add(new JButton("Button1"));
//OK
graphicsContext.draw(sv, rc.getRendererPane(), (int)center.getX(),
(int)center.getY(), size.width, size.height, true);
}
catch (Exception e)
{
System.err.println("Failed to render images!\n");
System.err.println("Caught Exception: " + e.getMessage());
}
}
}
public static void main(String[] args)
{
/*Create the window*/
JFrame frame = new JFrame("BLABLA");
Number[][] list = {{0, 1, 3}, {1, 3, 1}, {2, 2, 3}, {3, 2, 0}};
GraphPanel g = new GraphPanel(list);
g.attach_to_frame(frame);
frame.getContentPane().setPreferredSize(new Dimension(640, 480));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}/*2*/
Yes it is possible (I think). I would recommend you change your VertexLabeler to one that you implement yourself. Something in the lines of...
VisualizationImageServer<V, E> vv = new ...;
vv.getRenderContext().setVertexLabelRenderer(new MyVertexRenderer());
class MyVertexRenderer extends JFrame implements VertexLabelRenderer {}
But I'm not sure how it is going to work in terms of positioning it later. You might need to change the VertexShapeTransofrmer aswell with vv.getRenderContext().setVertexShapeTransformer().
I must say, I've spent a lot of time trying to get Jung to render a graph nicely like graphviz with very little success.