0

The JButton extends AbstractButton which has these default variables.

// Display properties
private boolean    paintBorder             = true;
private boolean    contentAreaFilled         = true;

I'd like said JButton created via the palette to have those as false.

I tried creating a new class and copied the code from AbstractButton (which would've been extended by a new type of JButton) and only changed those values, but some of the methods used inside are private and can not be accessed from a different package.

Even if I could access them from a different package, I'd need to also create a new custom Swing component - is there no simple way to do this?

Why am I trying to do this? I'll be creating a lot of buttons where those values will be false and I'd like to avoid having to set them via their respective methods for each one, if possible.

Edit 1:

IconButton.java - As suggested by Abra

import javax.swing.*;

public class IconButton extends JButton {

    public IconButton() {
        setContentAreaFilled(false);
        setBorderPainted(false);

    }
}

Adding the button programmatically via the code below, it works, but trying to add it via the Palette by drag-and-drop into the JPanel (Card Layout), doesn't work. Nothing happens, no error or anything.

MyForm.java

import components.IconButton;
import components.CustomIkon;
import com.formdev.flatlaf.FlatDarkLaf;
import org.kordamp.ikonli.materialdesign2.MaterialDesignA;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class MyForm extends JFrame {

    private JPanel mainPanel;
    private JButton normalButton;
    private JPanel testPanel;

    public MyForm(String title) {
        super(title);

        CustomIkon icon = CustomIkon.of(MaterialDesignA.ACCOUNT);

        normalButton.setIcon(icon);
        normalButton.setBorderPainted(false);
        normalButton.setContentAreaFilled(false);

        IconButton iconButton = new IconButton();
        iconButton.setIcon(icon);
        testPanel.add(iconButton);

        this.setContentPane(mainPanel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.pack();
    }


    public static void main(String[] args) {

        FlatDarkLaf.setup();

        JFrame frame = new MyForm("Hello World");
        frame.setVisible(true);
    }

}

I found a similar problem, but the answer there does not help. The JDK used by the project and the bytecode version are the same (in this case, version 16) in IntelliJ.

I'm investigating the log as suggested in the answer below the accepted one.

Edit 2:

I found this error in the log after the application was ran:

2021-06-27 18:39:12,264 [2711861]  ERROR - llij.ide.plugins.PluginManager - IconButton has been compiled by a more recent version of the Java Runtime (class file version 60.0), this version of the Java Runtime only recognizes class file versions up to 55.0 
2021-06-27 18:39:12,267 [2711864]  ERROR - llij.ide.plugins.PluginManager - IntelliJ IDEA 2021.1.2  Build #IC-211.7442.40 
2021-06-27 18:39:12,268 [2711865]  ERROR - llij.ide.plugins.PluginManager - JDK: 11.0.11; VM: Dynamic Code Evolution 64-Bit Server VM; Vendor: JetBrains s.r.o.

From what I understand, that means I'm compiling the application with a newer version than I am running it. Though, I don't see what that has to do with not being able to add the button from the palette to the form.

I'll keep investigating.

Edit 3:

Project Structure

Project

a) Project SDK: openjdk-16

b) Project language level: SDK default (16 - Records, patterns, local enums and interfaces)

Modules

a) Sources -> Language level: 16 - Records, patterns, local enums and interfaces

b) Dependencies -> Module SDK: Project SDK openjdk-16

SDKs -> openjdk-16

Settings

Java Compiler:

a) Use compiler: Javac

b) Project bytecode version: Same as language level

c) Per-module bytecode version -> Target bytecode version: 16

Java Version:

[username]:~/.jdks/openjdk-16.0.1/bin$ ./java -version
openjdk version "16.0.1" 2021-04-20
OpenJDK Runtime Environment (build 16.0.1+9-24)
OpenJDK 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)

Edit 4:

As suggested in some of the answers here, I went and checked the JDK that Maven uses (File -> Settings -> Build, Execution, Deployment -> Build Tools -> Maven -> Importing -> JDK for importer) and it was JRE version 11. I changed it to use the Project SDK.

After that, I invalidated the caches (File -> Invalidate Caches), deleted the target folder and ran my application again.

The error in the log mentioned in Edit 2 has disappeared.

Unfortunately, I still can't add the bloody IconButton from the palette to the JPanel.

Edit 5:

It seems the error mentioned in Edit 2 keeps appearing every time I try to drag-and-drop the IconButton from the palette to the JPanel, but not when I compile my application.

Removing and creating the component again doesn't seem to help.

Doombringer
  • 596
  • 4
  • 19
  • 1
    You write a new class that extends `javax.swing.JButton` and in your class constructor you call `setContentAreaFilled(false)` and you also call `setBorderPainted(false)`. Then, in _WindowBuilder_, you select your button from the palette rather than `JButton`. Is that not simple enough for you? – Abra Jun 27 '21 at 12:32
  • @Abra Thank for the response. That does indeed sound simple. Unfortunately, when I try to add my component to a `JPanel`, nothing happens. I tested with a normal `JButton` to make sure it wasn't the layout, and that one gets added with no issues. I also tried giving it a size via `this.setSize(new Dimension(radius, radius));` just in case, but that didn't help either. – Doombringer Jun 27 '21 at 13:36
  • I hope you realize that with the content area unfilled and no border, you will not see your button in _WindowBuilder_ - unless you select it in the _Components_ tree. By the way, I am using Eclipse 2021-06 on Windows 10 with JDK 11. – Abra Jun 27 '21 at 14:04
  • @Abra It doesn't show up in the *Components* tree either. I tried adding it there directly as well, but nothing happened. If there was at least an error, it'd be something, but not even that. I'm using the latest IntelliJ with OpenJDK 16. – Doombringer Jun 27 '21 at 14:12
  • I tried with an empty constructor and it **still** didn't show up. This is weird... – Doombringer Jun 27 '21 at 14:19
  • @Abra I restarted IntelliJ and now at least I'm getting an error. `Form contains components with Custom Create option but no createUIComponents() method`. I'll investigate and see if I find a solution to it. – Doombringer Jun 27 '21 at 14:34
  • rofl - I restarted IntelliJ again, the error disappeared but I can't add the component just like at the beginning. – Doombringer Jun 27 '21 at 15:01
  • On another note, the error was caused because I refactored it to test if it'll fix it. Deleting the `target` folder and running it again to rebuild it, fixes it. – Doombringer Jun 27 '21 at 15:07
  • Did some testing and it looks like I can add it to a `JPanel` programmatically, but I still cannot add it via the Palette (no errors or anything). – Doombringer Jun 27 '21 at 15:28
  • @DoombringerBG Could you post the code where it works with adding programmatically wit JPanel but not with Palette? –  Jun 27 '21 at 16:17
  • @vish I've edited my post with the info you requested. – Doombringer Jun 27 '21 at 16:35
  • @DoombringerBG This seems to refer to same but the new term I found is "default java". Perhaps that can help? https://intellij-support.jetbrains.com/hc/en-us/community/posts/206232369-Custom-Component-Class-Not-Found See answer from Aleksander Medella (Created March 13, 2020 02:20) –  Jun 27 '21 at 18:25
  • @vish Thank you. I'll try downgrading to 11 and see if that helps. – Doombringer Jun 27 '21 at 18:33
  • @vish Thank you, once again. Downgrading helped! Now I can add the `IconButton` from the palette to the form and it works as it should!!! – Doombringer Jun 27 '21 at 18:49

1 Answers1

0

(Using IntelliJ)

As suggested by Abra, create a custom button which extends JButton.

import javax.swing.*;

public class CustomButton extends JButton {

    public CustomButton() {
        setContentAreaFilled(false);
        setBorderPainted(false);
    }
}

After which, go to the palette and add your component:

Right-click -> Add Group -> Right-click on the group -> Add Component to Palette -> Choose the Class radio button -> Click on the [...] button and select your CustomButton class -> Click OK -> Check the Create binding automatically (optional - it'll create a variable in your form's class binding it to the component when you add it to the form).

If it let's you add the component after that but you get Form contains components with Custom Create option but no createUIComponents() method error, try pressing Ctrl+Shift+F9 (it'll select all of the components in the form and recompile them).

This error might also appear if you refactor the class. You might need to delete the target folder if it exists and/or invalidate the caches (File -> Invalidate Caches).

If your component appears in the palette but when you drag-and-drop it to the form nothing happens (i.e. doesn't add it), click on Help -> Show Log in File Manager.

Open it and check if you're getting an error similar to:

Custom Button has been compiled by a more recent version of the Java Runtime (class file version 60.0), this version of the Java Runtime only recognizes class file versions up to 55.0

If that's the case, thanks to Vish, you must downgrade to the version the Java Runtime recognizes or upgrade it (I don't know how to upgrade it, so in my case, I downgraded).

(Make sure to delete the custom component from the palette you created before proceeding, just in case.)

The easiest way to downgrade is to go to File -> Project Settings -> Project -> Project SDK -> Click the drop down menu -> Add SDK -> Download JDK -> Select version (in this case it's 11) and choose a Vendor (I went with AdoptOpenJDK(HotSpot)).

Then, download it and click the Apply button. After which, go to all of the Project Structure and Settings places mentioned in my Edit 3 and make sure they all have the same version assigned.

This also includes Maven/Gradle. In my case, I'm using the former, so I had to change the properties in the pom.xml file from 16 to 11.

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

If you forget to change it in the pom.xml/build.gradle file, when you try to run your application, you might get an error similar to:

By default, the Java language level is set to 5 which is not supported by the current Java version. Update the language level to 6+

Last but not least, if you forgot to delete the custom component from the palette before the downgrade/upgrade, do so now. If you still had your target folder after the downgrade/upgrade, delete it as well, after which invalidate caches once again.

Now you can create your custom component in the palette and everything should work.

Hope this was helpful.

Doombringer
  • 596
  • 4
  • 19