Android Studio code arrangement is strange when launching the "Rearrange Code" menu.
This bug probably comes from Android Studio Chipmunk 2021.2.1 Patch 1.
It seems android studio bug. How can I solve this issue?
prepare test code
public class Foo {
private final Runnable mFooRunnable1 = this::runFooRunnable2;
private final Runnable mFooRunnable2 = makeFooRunnable2();
public Foo() {
}
private Runnable makeFooRunnable2() {
return new Runnable() {
#Override
public void run() {
mFooRunnable1.run();
}
};
}
private void runFooRunnable2() {
mFooRunnable2.run();
}
}
menu -> Code -> Rearrange code
public class Foo {
public Foo() {
} private final Runnable mFooRunnable1 = this::runFooRunnable2;
private Runnable makeFooRunnable2() {
return new Runnable() {
#Override
public void run() {
mFooRunnable1.run();
}
};
} private final Runnable mFooRunnable2 = makeFooRunnable2();
private void runFooRunnable2() {
mFooRunnable2.run();
}
}
Related
So I have a loop class that is basically as follows:
public class Loop extends Thread {
private boolean running;
public Loop() {
running = false;
}
public void run() {
while(running) {
//Do stuff
}
}
public void setRunning(boolean b) {
running = b;
}
}
What I'd like to know is whether or not it is possible to store methods. For example the class could look like this instead.
public class Loop extends Thread {
private boolean running;
private Method method;
public Loop() {
running = false;
}
public void run() {
while(running) {
if(method != null)
method.callMethod();
}
}
public void setRunning(boolean b) {
running = b;
}
public void setMethod(Method m) {
method = m;
}
}
Is anything like this possible?
I assume you want this functionality in Java 6, so you can use interface and anonymous class.
Interface code:
public interface Listener {
void callMethod();
}
Your Thread:
public class Loop extends Thread {
private boolean running;
private Listener listener;
public Loop() {
running = false;
}
public void run() {
while(running) {
if(listener != null)
listener.callMethod();
}
}
public void setRunning(boolean b) {
running = b;
}
public void setListener(Listener listener) {
this.listener = listener;
}
}
Set Listener:
Loop loop = new Loop();
loop.setListener(new Listener() {
#Override
public void callMethod() {
// Do stuff
}
});
This will work for your usecase. If you want to save methods and pass methods as data, you have to either use Java 8 (not supported on all Android API levels) or Kotlin.
In java and android world, to run now Thread we execute it like this
Thread tr = new Thread(new Runnable() {
#Override
public void run() {
todo();
}
});
tr.start();
so tr is new Thread, but in android api PerformClick implements Runnable interface and is called normally by execute run method
private static void handleCallback(Message message) {
message.callback.run();
}
callback is PerformClick
private final class PerformClick implements Runnable {
#Override
public void run() {
performClick();
}
}
I am trying understand why for this case it is not new Thread
Thanks
I have a sub class of RecursiveTask which contains a Runnable object and should execute it.The problem is that the code inside the run method never gets reached although I use ForkJoinPool.execute in order to not block the main thread.
public class test {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
System.out.println("lo");
}
});
}
};
ATLockTask t = new ATLockTask();
t.runnable = r;
new ForkJoinPool().execute(t);
}
}
public class ATLockTask extends RecursiveTask<Object>{
public Runnable runnable;
#Override
protected Object compute() {
try {
runnable.run();
} catch (Exception e) {
logger.catching(e);
}
return null;
}
}
I want that my pdf chek method runs in the background but I really have no idea how I can implement my method into an SwingBackgroupWorker or Thread...
public class PDFCheck extends JPanel {
private void testAllFontsAreEmbedded(PDFDocument pdf) throws PDFDocumentException {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
this.problems.add(new ProblemDescription<PDFDocument>(pdf, "font not embedded: " + font.getName()));
}
}
}
}
Thank you very much...
I tried this code...but it doesn't seem to work..
public static class SwingBackgroupWorker extends SwingWorker<Object, Object> {
#Override
protected Object doInBackground() throws Exception {
private void testAllFontsAreEmbedded(PDFDocument pdf) throws PDFDocumentException {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
this.problems.add(new ProblemDescription<PDFDocument>(pdf, "font not embedded: " + font.getName()));
}
}
}
}
I would then start the backgroundworker with new SwingBackgroupWorker().execute();
}
How can I run the Backgroundworker to test it?
public class MoveIcon extends JPanel {
public class MyTask extends SwingWorker<Void, Void> {
#Override
protected Void doInBackground() throws Exception {
int i = 0;
while (i < 10) {
System.out.print(i);
i++;
}
return null;
}
}
public static void main(String[] args) {
new MyTask();
}
}
That doesn't work :(
I usually create inner classes for SwingWorkers. So you could put your SwingWorker in a private inner class of PDFCheck and add the fields (in your case just the pdf) you need to access inside your worker. You then can set them through the constructor. You could do something like this:
public class PDFCheck extends JPanel {
/* ... */
private class MyTask extends SwingWorker<Void, Void> {
PDFDocument pdf;
MyTask(PDFDocument pdf)
{
this.pdf = pdf;
}
#Override
protected Void doInBackground() throws Exception
{
for (PDFFont font : pdf.listFonts())
{
if (!font.isEmbedded())
{
PDFCheck.this.problems.add(new ProblemDescription<PDFDocument>(pdf, "font not embedded: " + font.getName()));
}
}
}
}
/* ... */
// Call the Swing Worker from outside the class through this method
public void runWorker()
{
MyTask task = new MyTask(pdfFile);
task.execute()
}
}
Call it then from inside the PDFCheck class like this:
MyTask task = new MyTask(pdf);
task.execute();
I have 2 classes .java
The main :
public class Controller extends javax.swing.JFrame
{
public static void updateProgressBar(int i) {
jProgressBar1.setValue(i);
jProgressBar1.repaint();
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Controller app = new Controller();
app.setVisible(true);
app.setResizable(false);
}
});
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
ChildModel model = new ChildModel();
Thread t1 = new Thread(model);
t1.start();
}
private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder
}
My ChildModel (ChildModel.java) computes some code (that takes around 10-20 sec) and I want to show the progress on the father class (Controller.java).
Here is my ChildModel :
public class ChildModel implements Runnable
{
public ChildModel(){ /* Something */ }
public void complexMath()
{
//Lots of logic here
Controller.updateProgression(purcent);
}
#Override
public void run() {
complexMath();
}
}
The problem is obviously my static void updateProgressBar that cannot modify a non-static variable. How can I accomplish this ?
The jProgressBar1 variable is an instance variable, so you can't access it from a static method. And the method shouldn't be static: you want to update the progress in the controller, and not in all the Controller instances.
Pass a reference to the controller to the ChildModel, and use this reference from the ChildModel in order to update the progress bar. Also remember that all Swing interactions must be done in the EDT, and not in a background thread. SO the code should look like this:
public class Controller extends javax.swing.JFrame
{
public void updateProgressBar(int i) {
jProgressBar1.setValue(i);
// no need for repaint. The progress bar knows it must be repainted
// when its value changes
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Controller app = new Controller();
app.setVisible(true);
app.setResizable(false);
}
});
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
ChildModel model = new ChildModel(this);
Thread t1 = new Thread(model);
t1.start();
}
private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder
}
public class ChildModel implements Runnable
{
private Controller controller;
public ChildModel(Controller controller){
this.controller = controller;
}
public void complexMath()
{
//Lots of logic here
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
controller.updateProgression(percent);
}
});
}
#Override
public void run() {
complexMath();
}
}
Swing has its own concurrency mechanisms to deal with updating components. Here you could use
a Swing Timer and update the JProgressBar. Rather than have ChildModel implement Runnable, you could use a Timer as a class member variable and pass in your instance jProgressBar1, enabling you to call setValue when required.