I tried to use ProgressBar as below:
ProgressBar Prog=new ProgressBar(0,100,50);
Prog.setValue(0)
//
BufferedReader bf = new BufferedReader(new FileReader(file1));
String line = bf.readLine();
while (line != null) {
lines.add(line);
Prog.setValue((int)(100*(double)lines.size()/MaxLen)); //ProgressBar will ot be updated
line = bf.readLine();
}
bf.close();
I also tried this method:
ProgressBar.DefaultProgressBarRenderer DP=new ProgressBar.DefaultProgressBarRenderer();
DP.drawComponent((TextGUIGraphics)gui.getScreen().newTextGraphics(),Prog );
GUI is MultiWindowTextGUI belong to contex, but it does not work because of Cast Problem:
com.googlecode.lanterna.screen.AbstractScreen$1 cannot be cast to com.googlecode.lanterna.gui2.TextGUIGraphics
Edit2:in component aproach, it need this:
Prog.setRenderer(new ProgressBar.DefaultProgressBarRenderer());
and a timer:
Timer timer = new Timer("ProgressBar-timer", true);
timer.schedule(new TimerTask() {
#Override
public void run() {
//Do some thing
}
}, 10, 10);
Assume you wanted to draw a progress-bar on the screen somehow.
Issue
But gui.getScreen().newTextGraphics() is giving TextGraphics and not desired TextGUIGraphics.
Draw on the screen
Given your renderer, you can use it to draw the progressBar on your screen.
Therefore, use the renderer's method drawComponent(TextGUIGraphics graphics, ProgressBar component):
// Given
MultiWindowTextGUI textGui = createGuiOn(screen);
TextGraphics textGraphics = screen.newTextGraphics();
// What you need, but don't get
TextGUIGraphics graphics = null; // WARNING: There is no method to get the graphics object from!
// Then
renderer.drawComponent( graphics, progressBar );
The drawing is a low-level rendering action. See Tutorial 3.
And there seems neither a constructor, nor a public method, that gives you that TextGUIGraphics, see the search on the GitHub repo.
Instead consider to work with components like ProgressBar.
Work with components
ProgressBar is a component. So you can add it simply to your TextGUI:
final Window window = new BasicWindow("My Root Window"); // create window
window.setComponent(progressBar); // set component of window
textGUI.addWindowAndWait(window); // add window to gui
See Tutorial 4 for working with components.
Related
I am trying to return an ArrayList with two values, text and a text area. However when I press the button that is meant to do this, nothing happens. Can you please explain why this is the case?
The method that returns the ArrayList:
public ArrayList<Object> newFile(){
ArrayList<Object> objectArrayList = new ArrayList<>();
TextArea textField = new TextArea("Type File Information.., ");
AtomicReference<String> fileText = new AtomicReference<>();
textField.addTextListener((textListener) -> {
fileText.set(textField.getText());
});
objectArrayList.add(String.valueOf(fileText));
objectArrayList.add(textField);
return objectArrayList;
}
}
The code snippet that executes the method and gets the text area:
public void actionPerformed(ActionEvent e) {
String action = e.getActionCommand();
switch (action) {
case "New":
fileText = (String) newFile().get(0);
MainMenu mainMenu = new MainMenu();
mainMenu.add((TextArea)newFile().get(1));
break;
The code snippet where I add the handler:
newFile.addActionListener(mainMenuHandler);
Why are you using AWT. You should at least be using Swing.
MainMenu mainMenu = new MainMenu();
mainMenu.add((TextArea)newFile().get(1));
In your case you add the text area to the MainMenu, but you never add the MainMenu to the frame.
So you would need to add the "mainMenu" to the frame.
Also, when using Swing if you add a component to a visible frame then you need to invoke revalidate() and repaint() on the container you add the component to.
Before you read, this will be informative: Java JFrame won't show up after using .setVisible(true) after being invisible
Hello I am working on a library API that let's you capture an area of the screen, and it returns you a class that contains the ByteArrayInputStream and utility methods like createBufferedImage, createFile, etc.
Basically you create a Bootstrap instance, and pass the capturer type you want as a dependency (ScreenshotCapturer or GifCapturer):
Bootstrap b = new Bootstrap(new ScreenshotCapturer());
And the beginCapture method receives an object that implements ScreenCaptureCallback which is the callback event that the captured result will be passed to.
This is a short background.
Now when you use the beginCapture method, basically what it does is creates new instance of SelectionCamera, this is basically the component that paints the selection area you're selecting when dragging the mouse, and updates the listeners.
once created instance, it calls super.setVisible(true);
After that method gets called, the frame will show up, and also show the old painted screen for like 600-500miliseconds, I am not exactly sure, but it disappears so quickly.
Take a look at this live example:
Note use the video option, otherwise you will not see what I'm seeing as gif is too slow to show it!
http://gyazo.com/d2f0432ada37842966b42dfd87be4240
You can see after I click Screenshot again, it shows the old selected area and disappears quickly. (by the way the frame you see in the gif is not part of the app, just dummy hello world example usage).
The process of image capture.
Step 1
beginCapture gets called:
public void beginCapture(final ScreenCaptureCallback c) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
capturer.setCallback(c);
capturer.beginSelection();
}
});
}
Step 2
beginSelection gets called in the Capturer class (ScreenshotCapturer extends Capturer (abstract)
#Override
public void beginSelection() {
super.init();
this.setHotkeys();
super.getCamera().startSelection();
}
Step 3
CaptureCamera#startSelection() gets called
public void startSelection() {
super.getContentPane().removeAll();
super.getContentPane().repaint();
super.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
this.selector = new SelectionCamera();
this.selectionMosueAdapter.updateCamera(this.selector);
this.selectionMouseMotion.updateCamera(this.selector);
super.add(this.selector);
super.setVisible(true);
super.repaint();
super.getContentPane().repaint();
}
Step 4
The user selects an area, and both mouse listener and mouse motion listens to it(Take a look at mouse motion):
#Override
public void mouseDragged(MouseEvent e) {
Point dragPoint = e.getPoint();
Point startPoint = this.selector.getStartPoint();
int x = Math.min(startPoint.x, dragPoint.x);
int y = Math.min(startPoint.y, dragPoint.y);
int width = Math.max(startPoint.x - dragPoint.x, dragPoint.x - startPoint.x);
int height = Math.max(startPoint.y - dragPoint.y, dragPoint.y - startPoint.y);
this.selector.setCameraDimension(width, height);
this.selector.setCoordinates(x, y);
this.camera.repaint(); // important
}
by the way this.selector is SelectorCamera which is the component that paints the selection area.
Step 5
CaptureCamera#endSelection() gets called, this method gets the x,y, width, height from the selection camera and passes it to the capturer class which uses Robot to get screenshot with that rectangle, and before that it removes ALL components from the content pane, and repaints everything and then sets visibility to false.
public void endSelection() {
super.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
int x = this.selector.getCameraX();
int y = this.selector.getCameraY();
int w = this.selector.getCameraWidth();
int h = this.selector.getCameraHeight();
super.getContentPane().removeAll();
super.getContentPane().repaint();
//super.repaint();
super.setVisible(false);
this.c.startCapturing(x, y, w, h);
}
Basically this is the last step, rest steps are unnecessary for the debugging as it only sends back the callback.
I really tried my best explaining the process of my application, I've tried figuring it out for 5 and half hours now, and no luck at all. Tried different ways, by creating new SelectionCamera object as you see, doesn't work.
Why is it doing this? Is it something to do with the swing core?
SelectionCamera code: https://github.com/BenBeri/WiseCapturer/blob/master/src/il/ben/wise/SelectionCamera.java
Thanks in advance.
Based on this example...
try {
final Bootstrap b = new Bootstrap(new ScreenshotCapturer());
b.beginCapture(new ScreenCaptureCallback() {
#Override
public void captureEnded(CapturedImage img) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
b.beginCapture(new ScreenCaptureCallback() {
#Override
public void captureEnded(CapturedImage img) {
System.out.println("...");
JFrame frame = new JFrame();
frame.add(new JLabel(new ImageIcon(img.getBufferedImage())));
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
});
}
});
System.out.println("Hello");
} catch (AWTException exp) {
exp.printStackTrace();
}
I won't focus on the initialise stage of the first round, I will focus on the initialisation of the second round as this is where the problem is...
b.beginCapture call's this.capturer.beginSelection();, which calls super.getCamera().startSelection(); which calls setVisible(true) (CaptureCamera been a JFrame).
This will immediately show what ever was previously displayed on the CaptureCamera. It's important to note here, that no new instances of objects were created through the process...
Now, I made a lot of changes to the base testing this, but it appears that the problem is with the restoration of the frame when it's made visible for the second time. This seems to be an issue with the transparency support of the Window as it seems to restore the last "known" state instead of repainting the window immediately...
Now, I tried clearing the selector before making the CaptureCamera invisible to no eval, as the window seems to be made invisible before the selector is painted.
The final solution I came up with was to call dispose on the CaptureCamera, which releases it's native peer and therefore destroys the old graphics context, forcing the frame to rebuild itself when it is made visible again.
"A" problem with this could be the fact that when all the windows are disposed (and the only running threads are daemon threads), the JVM will exit...
This was an issue during my testing as I was using a javax.swing.Timer to put a delay between the first and second capture process so I could see where the problem was occurring and this caused my JVM to exit (as the timer uses a daemon thread and I had no other windows open).
I got around this by creating a tiny (1x1) transparent window in the Capturer class, keep this in mind if the JVM exists gracefully for no reason ;)
Side Notes...
Now, there is an issue with SelectionCamera (which extends JPanel), it is opaque, but is using a transparent background, this is incredibly dangerous as Swing only knows how to deal with opaque or fully transparent components.
public SelectionCamera() {
super.setBackground(new Color(0, 0, 0, 0));
super.setVisible(false);
}
Should be updated to something like...
public SelectionCamera() {
setOpaque(false);
//super.setBackground(new Color(0, 0, 0, 0));
super.setVisible(false);
}
I'm also confused over the use of super.xxx, the only reason you would do this is if you had overrriden those methods and didn't want to call them at this time...In my testing, I removed all the calls to super where a method wasn't overridden in the current class (and I wasn't already in the overriden method)
Also, the paintComponent method should be calling super.paintComponent
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(0, 0, 0, 0.5f));
g.fillRect(this.x, this.y, this.width, this.height);
}
Make Frame left to be -10,000 then set visible true, add a timer 2 seconds (try lower to 25-100 milliseconds, just to give it sligth pause to invalidate content) , on timer :left to 0 . I think it works due to caching & double buffereing. Frame shows what it had in buffer, buffer points to old image due to caching/ lazy repaint.
Alternative :
Maybe a repaint or invalidate before your show would work too, and don't need to do the left -10,000. I dont work much with ui-swing, just a but years back and remember some strange things like this.
For organization's sake, I use multiple scenes for my game and rather than having each scene have a constructor that receives a Viewport (my game is scalable), I would like to set each stage's viewport separate of the constructor, then after the viewport is set, add the actors. In the main class, it would happen like this:
public void setStage(Stage s)
{
if(currentStage != null)
currentStage.dispose();
currentStage = s;
currentStage.setViewport(view);
}
To make this go fluidly, each stage has an init method that is called within an overriden setViewport:
#Override
public void setViewport(Viewport v)
{
super.setViewport(v);
init();
}
However, all this gives me is a black screen... I have tried updating the camera and viewport, but no avail (note that the actors are having their render methods called).
Why am I getting this black screen and how do I fix it? If it's not possible I'll just revert to using the constructor.
If I understood correctly you want to do this:
Stage stage1 = new Stage();
stage1.getViewport().update(width, height);
rather than this:
Stage stage1 = new Stage (new StretchViewport(width, height)); // It doesn't have to be StretchViewport
In the first case (what you are trying to do) a ScalingViewport will be costructed automatically for you with dimensions of the Gdx.graphics and an orthographic camera and acts like a StretchViewport. Why not using the second case directly where you pass the viewport you want. You can always alter your viewport whenever you want by calling stage1.getViewport().update(width, height);
or by calling stage1.setViewport(width, height, false); in older Libgdx versions.
Viewport has changed recently so if you can extend Viewport class to Override the update method maybe you can achieve what you want:
public class ViewportExtendClass extends StretchViewport{
public ViewportExtendClass(float worldWidth, float worldHeight) {
super(worldWidth, worldHeight);
}
#Override
public void update (int screenWidth, int screenHeight, boolean centerCamera) {
super.update(screenWidth, screenHeight, centerCamera);
// DO YOUR INITIALIZATION HERE
}
}
From your main class you create new stage :
Stage stage1 = new Stage (new ViewportExtendClass (width, height));
and then you call :
stage1.getViewport().update(width, height);
Like this you can alter stage viewport and re initialize your assets.
#Override
public void setViewport(Viewport v)
{
super.setViewport(v);
this.getViewport().update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
Camera c = this.getViewport().getCamera();
c.position.set(c.viewportWidth/2, c.viewportHeight/2, 0);
init();
}
This works, but you should also be able to update the Viewport like that at the begin of your application, if you continue to use the same one. I set the position like that instead of centering because some of my Stages will be larger than the screen.
I have two button listeners for game board using java swing.
A tetris grid is created initially and then addition functionality within each button listener.
I set the board up like so in my Play.java:
final TetrisGame g = new TetrisGame(11,1);
final BoardGraphics graphics = new BoardGraphics(TetrisBoard.BOARD_WIDTH, 40, g);
The button listeners are then created in the same Play.java:
graphics.btnStart.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Action arc = p.getAction(g);
g.update(arc);
graphics.colours.clear();
graphics.setColor(g.getBoard().getGrid());
while (arc instanceof Store){
arc = p.getAction(g);
g.update(arc);
graphics.colours.clear();
graphics.setColor(g.getBoard().getGrid());
}
graphics.tiles.redraw();
System.out.println();
System.out.println(g.toString());
System.out.println();
}
});
graphics.btnAuto.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
while (!g.gameEnded()){
Action arc = p.getAction(g);
g.update(arc);
graphics.colours.clear();
graphics.setColor(g.getBoard().getGrid());
while (arc instanceof Store){
arc = p.getAction(g);
g.update(arc);
//graphics.colours.clear();
graphics.setColor(g.getBoard().getGrid());
}
graphics.tiles.redraw();
System.out.println();
System.out.println(g.toString());
System.out.println();
/*try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}*/
}
}
});
The btnStart works perfectly, pressing it once, painting the tetrisboard according to the next move given by AI agent.
I would like the btnAuto to play each move out without the user pressing btnStart to generate move until the end. However, my btnAuto does not paint anything on to the grid but the final state of the game, the finishing state.
Can anyone see why this might be not repainting the grid after each move is generated in the while loop?
Your while loop is being called on the Swing event thread and is thus preventing the the thread from doing its necessary actions including rendering the GUI and interacting with the user:
while (!g.gameEnded()){
Action arc = p.getAction(g);
// ....
}
I would use a Swing Timer here instead of a while (true) loop. Another option is to use a background thread, but since all you desire is a very simple game loop and don't need to run some long-running in the background, I think that this second option would be more complex with no additional benefit.
As an aside, I'm curious how you're doing your drawing and how you're getting your Graphics object to draw with. You're not calling getGraphics() on a component, are you?
Edit you state in a comment:
I currently have a class with a nested class that extends JPanel. The drawing of the grid and getGraphics() is done within the nested class.The parent class creates the component and sets the layout of the GUI as a whole
Don't get a Graphics object by calling getGraphics() on a GUI component as the Graphics object obtained will not persist. To see that this is so, simply minimize and then restore your application and tell me what happens to your graphics after doing this. You should do all of your drawing in the JPanel's paintComponent override. One option is to call getGraphics() on a BufferedImage and use it to draw to the BufferedImage, and then display the BufferedImage in the paintComponent override. If you use the second technique, don't forget to dispose of the BufferedImage's Graphics object after you are done using it so that you don't hog system resources.
I coded a j2me application using LWUIT. It works fine on emulator as well as a symbian device. But when i tried to run it on a nokia s40 device,it showed up a "nothing to display" message. I tried displaying a splash screen, as prescribed in some forums. Still,the app never gets past the splash screen.
EDIT 1
Display.init(this);
Resources r = Resources.open("/theme.res");
UIManager.getInstance().setThemeProps(r.getTheme(r.getThemeResourceNames()[0]));
Dialog splash = new Dialog("Splash Screen");
splash.setAutoDispose(true);
splash.setTimeout(5000);
splash.show();
RecordStore rs = null;
byte[] buffer = null;
rs = RecordStore.openRecordStore("xxxxxx", true);
if (rs.getNumRecords() > 0) {
buffer = rs.getRecord(rs.getNumRecords());
num = new String(buffer, 0, buffer.length);
rs.closeRecordStore();
offer(num); // a method which displays main form
} else {
rs.closeRecordStore();
registration("xxxxx"); //another method which displays the secondary form
}
In this snippet,a blank screen is displayed on the device after the dialog/splash screen.
The form gets displayed when i remove the codes managing the RecordStore.
How do i fix this mess ?
EDIT 2
Code for registration()
Form f = new Form();
f.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
Image img = Image.createImage("logo.png");
f.addComponent(new Label(img));
Label lbl = new Label(msg);
f.addComponent(lbl);
f.addComponent(new Label("xxxxx"));
final TextArea number = new TextArea(1, 10, TextArea.NUMERIC);
f.addComponent(number);
Button btn = new Button("Register");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//perform rms related activities and move onto offer()
}
});
f.addComponent(btn);
Button help = new Button("Help?");
help.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//display a help dialog
}
});
f.addComponent(help);
f.addCommandListener(this);
f.show();
Change the splash.show() to splash.showModeless()
Regardless your code is incorrect since it assumes show() will display the dialog immediately which is not how most GUI frameworks work. Your method needs to complete and return control to LWUIT in order for the dialog to show. However, you read the RMS and then the code to show your form is unclear, when do you expect it to actually occur.
You need to show the dialog without a timeout (I would use a form for the splash screen there is no reason to use a dialog), then open a thread (new Thread(...)) to do whatever you want and then when the thread completes show your form.
From this blog, The Nothing to display issue is standard Nokia S40 behavior for delayed calls to setCurrent() and the normal recommendation is to show a splash screen early on to avoid this prompt.
Also look this same related discussion.
Edit:
Form splashscreen = new Form();
splashscreen.getStyle().setBgImage(imageName);
splashscreen.show()
Display.getInstance().callSerially(new Runnable() {
public void run() {
try {
Thread.sleep(5000L);
// do RMS related things here.
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
});