Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
In general, I do not tend to ask for help when it comes to bug fixing, however, I have a very weird one I have spent 2 days trying to fix it without any success. My class is basically a roulette with multiple dificulties so, I used a pieChart to change the dificulties and redraw the roulette fast and with the cool animations that comes with pieChart, however, the method that makes my roulette roll to a certain angle has a big problem, after the RotateTransition ends the GUI freezes complitly. I don´t know why, cause i have other RotateTranstions in other clases and they work fine, also, if i remove the rotateTransition or use other component in it (i tried using images insted of pieChart) it works just fine. I don´t know if pieChart has something special that makes it imposible to use with RotateTransition, also the only exeption to the freeze is the button that allow me to bet again, and yes i already tried "Platform.runLatter()"
#Override
public void initialize(URL url, ResourceBundle rb) {
rotateTransition = new RotateTransition();
rotateTransition.setNode(pieChart);
rotateTransition.setDuration(Duration.seconds(1));
rotateTransition.setByAngle(-360);
rotateTransition.setCycleCount(1);
rotateTransition.setAutoReverse(false);
pieChart.setData(dataForX1_5);
pieChart.setStartAngle(90);
applyDataWithCustomColor(dataForX1_5, "green", "red");
betButton.setOnAction(eh -> {
double betMultiplier=1.5;
if(rbX1_5==group.getSelectedToggle()){
pieChart.setData(dataForX1_5);
applyDataWithCustomColor(dataForX1_5, "green", "red");
betMultiplier=1.5;
}
if(rbX2==group.getSelectedToggle()){
pieChart.setData(dataForX2);
applyDataWithCustomColor(dataForX2, "green", "red");
betMultiplier=2;
}
if(rbX5==group.getSelectedToggle()){
pieChart.setData(dataForX5);
applyDataWithCustomColor(dataForX5, "green", "red");
betMultiplier=5;
}
if(rbX10==group.getSelectedToggle()){
pieChart.setData(dataForX10);
applyDataWithCustomColor(dataForX10, "green", "red");
betMultiplier=10;
}
if(rbX25==group.getSelectedToggle()){
pieChart.setData(dataForX25);
applyDataWithCustomColor(dataForX25, "green", "red");
betMultiplier=25;
}
if(rbX50==group.getSelectedToggle()){
pieChart.setData(dataForX50);
applyDataWithCustomColor(dataForX50, "green", "red");
betMultiplier=50;
}
try {
int betAmount = betAmountSpinner.getValue();
int spectedResult = (int) (betAmount * betMultiplier);
if (coins >= betAmount) {
dataOutputStream.writeUTF("PlaceBetOnUpgrade");
dataOutputStream.writeInt(betAmount);
dataOutputStream.writeInt(spectedResult);
if (dataInputStream.readBoolean()) {
int result = dataInputStream.readInt();
int payment = dataInputStream.readInt();
coins = coins - betAmount;
rotateTo(result, payment);
updateCoinsLabel();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
private void rotateTo(int result, int payment) {
rotateTransition.setToAngle(result * 3.60);
rotateTransition.setOnFinished(rotateEvent -> {
if (0 == payment) {
resultLabel.setText("Lost");
} else {
resultLabel.setText("Win");
coins = coins + payment;
updateCoinsLabel();
}
});
rotateTransition.play();
}
private void updateCoinsLabel() {
coinsLabel.setText(String.valueOf(coins));
}
Well i endend up findind the solution to my problem and it was exactly where i said i should be. The problem is that even though you can technically rotate a pieChart using RotateTransition, you have to be aware that when doing it, you are not only rotating the pieChart that you see on the screen but also a transparent layer that is behind it and that even when disable the labels and legends will ocuppy the form of a rectangular with the max posible size. Therefore, when you rotate the pieChart the transparent layer will overlap all your components causing a freeze without any exception. The solution that most would recommend is just to set it as mouse transparent and allow click penetration but, it won´t work, cause it is bugged and will only allow the click penetration in the pieChart but not in the transparent layer, so if you want to rotate a pieChart you need it to be in the center of the screen so even if it roates to a 90º angle it will only overlap the things that are outside of the screen, so it doesn´t matter. if you need to place it elsewhere, you will need to set its max size to something diferent to Max_size and check that it nevers ovelaps anywhing, however, it certainly limits your view quality in high resolutions.
Related
so lately i've been learning about abstract classes and interfaces, and i saw a neat yt video about falling sand games (think Noita) so i wanted to take a crack at it as some particles share a characteristic that can be abstracted, and behavior that's not specific to only particles that can be interfaced. only going to be implementing 2, maybe 3 types of "particle" but it seems im having trouble with gravity.
i've spent a few hours trying to figure out a good way of doing it and this is what i got so far out of my attempts (which include: gravity somehow working backwards, collision being ignored, and working, but sunk a few pixels into the object)
// the drop method is called every second, and force == 1
// drop is a method from the Gravity interface, Sand implements gravity and overrides drop.
#Override
public void drop(Particle self) {
for (Particle p : Controller.particle) {
if (p.equals(self)) {
continue;
}
if (self.rectangle.getBoundsInParent().intersects(p.rectangle.getBoundsInParent())) {
Behavior.repulseUpward(self, force);
}
}
Behavior.gravityDrop(self, force);
}
public class Behavior {
static void gravityDrop(Particle p, double force) {
// in the future ill replace bottomLine with what's inside it but for now its more
// readable to me.
double bottomLine = (Controller.height - p.rectangle.getHeight());
if (p.rectangle.getLayoutY() < bottomLine) {
p.setPosition(p.rectangle.getLayoutX(), p.rectangle.getLayoutY() + force);
}
}
static void repulseUpward(Particle p, double force) {
p.setPosition(p.rectangle.getLayoutX(), p.rectangle.getLayoutY() - force);
}
}
(if i've forgotton any code that you think would be relevant ill add it)
this gives me the behavior i was hoping for! exceeeeeept if say two shapes are 20 pix wide, and are spaced 20 pix apart, it will still detect a collision and cause themselves to suspend in air. Is there any fix to get around this situation or do i have to scrap the drop method again?
Picture of the problem here
I am writing an app that generates Maths worksheets for school students. It will, for example, generate 2 to 5 pages of simple Maths questions and 1 to 2 pages of answers. The PDF can be saved to file and loaded again later. Then it has a print function that can print all the pages. I want to make it skip printing the answer pages.
Is it possible to automatically identify which pages are the answer pages? I can only think of a workaround by making those answer pages have special height or width but not even sure if this works. Are there any better ways to do this?
Ok, I continued the project and used the following method: when constructing the PDF, I put the word "Answer on the top left corner with a gray rectangle surrounding it drawn with drawRect(). Then before the actual printing, I used the following code inside the PrintDocumentAdapter() class to check whether the color of the pixel 0,0 is gray or not.
#Override
public void onStart() {
if (parcelFileDescriptor != null) {
try {
pdfRenderer = new PdfRenderer(parcelFileDescriptor);
} catch (IOException e) {
e.printStackTrace();
}
}
int tempTotal = pdfRenderer.getPageCount();
Bitmap[] tempBitmap = new Bitmap[tempTotal];
finalTotal = tempTotal;
for (int pageNum = 0; pageNum < tempTotal; pageNum++) {
PdfRenderer.Page tempPage = pdfRenderer.openPage(pageNum);
tempBitmap[pageNum] = Bitmap.createBitmap(WS_WIDTH, WS_HEIGHT, Bitmap.Config.ARGB_8888);
tempPage.render(tempBitmap[pageNum], null, null, PdfRenderer.Page.RENDER_MODE_FOR_PRINT);
if (tempBitmap[pageNum].getPixel(0, 0) == Color.GRAY) {
finalTotal--;
}
tempPage.close();
}
}
It works fine. At least should cause no problem if the users only attempt to print PDF files constructed with my app. :P
Please tell me if you know a better way to do this. Thanks!
I am having issues with my java application and I can't find a suitable reply.
In summary a right click triggered default pop up menu changes my chart's background color behind the pop up.
You can find images below. I am happy to keep the default popup without the "buggy" behaviour or develop my own if required.
A click of a button starts a stream of data and adds a chart to a JInternalFrame component:
If I right click on the image a default pop up comes up:
If I then click away the rectangle area covered by the popup will overlay the chart like this:
TimeseriesMonitorModel model = new DefaultTweetMonitorModel();
jif.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
try {
jif.setContentPane(new TweetSeriesChartPane(model, TweetMonitor.keywords, tkc));
jif.setSize(jif.getWidth(), jif.getHeight());
} catch (InterruptedException ex) {
Logger.getLogger(TweetMonitor.class.getName()).log(Level.SEVERE, null, ex);
}
jif.setVisible(true);
where jif is the Jinternalframe and
public TweetSeriesChartPane(TimeseriesMonitorModel model, String[] seriesNames, TweetKeywordCount tkc) throws InterruptedException {
this.seriesNames = seriesNames;
this.tkc = tkc;
this.model = model;
XYChartTimeseries myRealTimeChart = new XYChartTimeseries();
chart = myRealTimeChart.getChartWithTitle();
List[] tweetData = model.getFrequencyCount(new AtomicIntegerArray(seriesNames.length)); // we are starting from 0
int i = 0;
for (String keyword : seriesNames) {
List<Integer> yData = (List<Integer>) tweetData[1].get(i);
chart.addSeries(keyword, tweetData[0], yData); // adding first value
i++;
}
setLayout(new BorderLayout());
XChartPanel<XYChart> chartPane = new XChartPanel<>(chart);
add(chartPane);
UpdateWorker worker = new UpdateWorker(this, seriesNames, this.tkc);
worker.execute();
}
I've managed to temporary solve the above.
I've checked specifically this line of code
XChartPanel<XYChart> chartPane = new XChartPanel<>(chart);
which extends Chart and Jpanel. The code is from the knowm-chart dependency https://github.com/knowm/XChart/blob/develop/xchart/src/main/java/org/knowm/xchart/XChartPanel.java)
Apparently it adds a listener and the customized PopUpMenu. After reviewing it, it looks like it didn't do any repainting when the mouse was clicked outside the PopUpMenu area.
So I created a new class and tried to customise it. However, the repaint was flickering the screen and I couldn't get it to work only in the PopUpMenu area.
I ended up disabling the .addMouseListener call so now I don't get any popUpMenu. I sad compromise, but oh well.
BTW:
Thanks to both, regardless of the last unneeded comment which didn't add any value.
I did read the link and I though I provided enough information.
In any case, posting to code helped me troubleshoot it
I checked some questions here but I couldn't find a proper answer. Maybe I am using wrong keywords to search. But what I found didn't help. So here is my question. I have some circles and line that are sliding in a certain way.
What I want is to update balance variable after the animations perform.
DoubleProperty balance = new SimpleDoubleProperty();
And I update the balance as follows:
if (shapeADone == false) {
intersecting = arc.centerXProperty().lessThan(boldLine.getEndX() - 13);
intersecting.addListener((obs, wasIntersecting, isNowIntersecting) -> {
System.out.println("Collision!");
animation1.stop();
animation2.stop();
animation3.stop();
});
again = true;
balance.setValue(-1);
} else {
fadeB();
balance.setValue(1);
}
But in main method I want to do something like this
level1.balance.addListener(ov -> {
System.out.println("The new value is " +
level1.balance.doubleValue());
if (level1.balance.getValue()==1) {
//delay setting scene
primaryStage.setScene(scene2);
}
});
I have some animations to perform before setting scene2 but since balance instantly updating, my animations can't be performed.
I want to know if there is a way to delay listening balance or setting scene.
I tried Thread.sleep and balance.wait but it gives runtime errors.
Edit: This question clearly shows that I was lack of knowlodge about javafx. What I want to do is simple and solution is even more simple. When animation perform to the end I update the value of balance. All I wanted was make sure that animation is showed to the end.
Here is the answer :
else{
animation3.setOnFinished(event -> balance.setValue(1));
fadeB();
}
As Sedrick's comment I change the code like this.
Adding setOnFinish to animations which need to be performed solve the problem. It's working.
I created a live wallpaper service using AndEngine library. On screen there are a number of bird Sprite objects that flying repeatedly from the left to right started in random y-coordinate (I'm using LoopEntityModifier and PathModifier for this, see my previous question if you're curious). The birds shouldn't start flying in same time, but there is a gap/interval about 3 seconds before another bird showed up from left most screen.
The question is what technique that I have to use to achieve that?
I had created array of Sprites to hold the bird sprites. The code is like this...
public class MyLiveWallpaperService extends BaseLiveWallpaperService {
private BirdSprite[] birdSprites; // BirdSprite is actually an extension class from AnimatedSprite
...
#Override
public Scene onLoadScene() {
...
birdSprites= new BirdSprite[4];
for (int i=0; i<4; ++i) {
birdSprites[i] = new BirdSprite(0, 0, birdTextureRegion);
scene.getChild(LAYER_FRONT).attachChild(birdSprites[i]);
}
}
}
The above code produces four birds that show-up on left screen in same time. I tried by adding Thread.sleep(3000) before calling attachChild, but it affects whole application. The live wallpapaper application become hanged for several seconds when started.
This is the solution I found by using TimerHandler:
scene.registerUpdateHandler(new TimerHandler(3, true, new ITimerCallback() {
#Override
public void onTimePassed(TimerHandler pTimerHandler) {
// your code here will be executed every 3 seconds (see 1st argument of TimerHandler)
...
scene.getChild(LAYER_FRONT).attachChild(birdSprites[i]);
}
}));
Please let me know if you have better solution.