More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

More work on centralizing icon loading to ImageUtilities - #8194

Merged
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more
Feb 24, 2025
Merged

More work on centralizing icon loading to ImageUtilities#8194
eirikbakke merged 2 commits into
apache:masterfrom
eirikbakke:pr-loadicon-more

Conversation

@eirikbakke

@eirikbakkeeirikbakke commented Jan 25, 2025

Copy link
Copy Markdown
Contributor

This is a follow-up on the separate work in #8114 and #8109 . To render at full HiDPI resolution, with SVG icon substitutions where available, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.

This PR, combined with the previously mentioned PRs, handles most of the remaining cases.

Specifically:

  • Search for new ImageIcon( and rewrite each relevant case to use ImageUtilities to load icons instead.
    • In many cases this means replacing new ImageIcon(SomeClassInCurrentModule.class.getResource("/package/folders/path/to/icon.png")) to ImageUtilities.loadIcon("package/folders/path/to/icon.png"). I verified visually in the IDE that this worked in one case (the Print dialog), to make sure this is a valid transformation. In cases where a relative path was previously used, I replaced it with an absolute path that I looked up manually (this page is helpful for this). Note that ImageUtilities does not want leading slashes.
    • The CompletionProvider API requires ImageIcon to be used. The ImageUtilities.icon2ImageIcon method is used to produce a special version of ImageIcon that supports HiDPI scaling in these cases.
  • Search for instanceof ImageIcon and generalize to instanceof Icon when appropriate.
  • Search for getLookAndFeel*getDisabledIcon and switch to ImageUtilities.createDisabledIcon.
  • Search for loadImageIcon("/ and remove the leading slash in some cases (which would produce a warning log entry). Also switch to loadIcon if possible if I'm already changing these lines.
  • Deleted some commented or unused code in some cases, to prevent irrelevant code from showing up when searching for places to refactor.

Places where uses of new ImageIcon were left unmodified include:

  • Test classes
  • Classes relating to loading and display of arbitrary icons, e.g. the property editor for Icon instances.
  • Places where the ImageIcon is simply used as an empty icon.
  • Installer-related modules.

It'll be good to test these changes in development builds for a while, in case icon loading breaks accidentally somewhere. I'll start doing so in my own working IDE now. (I already tested the separate changes in #8109 for three weeks.)

@eirikbakkeeirikbakke added Code cleanup Label for cleanup done on the Netbeans IDE Platform [ci] enable platform tests (platform/*) UI User Interface ci:all-tests [ci] enable all tests ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jan 25, 2025
@eirikbakke
eirikbakkeforce-pushed the pr-loadicon-more branch 2 times, most recently from 26e9b10 to 5d2e131CompareJanuary 25, 2025 20:54
@eirikbakkeeirikbakke added this to the NB26 milestone Jan 25, 2025

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Wondering if you considered using jackpot for (some of) the migration rules?

e.g.: https://github.com/apache/netbeans/blob/master/platform/openide.filesystems/src/META-INF/upgrade/Repository.hint

@eirikbakke

eirikbakke commented Jan 26, 2025

Copy link
Copy Markdown
ContributorAuthor

@mbien Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

In any case I think this is the last batch of bulk changes to ImageIcon-related stuff.

@mbien

Copy link
Copy Markdown
Member

Didn't know about Jackpot rules! I did these edits manually, in particular since there were a lot of small variations in how loading was done or how simplifications could be made.

yeah I didn't mention it earlier for that reason. But jackpot rules can be quite useful sometimes and I feel not enough know about them - so I make sure to point that out when the opportunity arises ;) They could be also put into the meta-inf of a module and used to help with migration third party code too.

For personal use, they can be put into conf/rules. I have a bunch of them active most of the time.

for example try putting this into a hint file in conf/rules and open profiler/profiler.heapwalker/src/org/netbeans/modules/profiler/heapwalk/model/BrowserUtils.java pre-refactoring:

newjavax.swing.ImageIcon(org.openide.util.ImageUtilities.mergeImages($a.getImage(), $b.getImage(), $c, $d))
=>
org.openide.util.ImageUtilities.icon2ImageIcon(org.openide.util.ImageUtilities.mergeIcons($a, $b, $c, $d))
;;

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

I know it's off-topic but there's one Jackpot rule I would love to have, which is similar to "Assign Return Value to New Variable", except using the return value as an iterable for a for loop. E.g. "Iterate over Expression in for Loop":

someIterableOfFooType

becomes

for (FooType fooType : someIterableOfFooType) {
}

Is that a rule you would know how to write off the top of your head? (Ideally it would work when FooType has generic parameters, too.)

@mbien

Copy link
Copy Markdown
Member

Oh, that's neat! I got that to work. Note that the folder in the home directory is called "config" rather than "conf", at least in my case. (Would also be useful in your readme to say "config/rules/" with a slash at the end to make it clear that rules is a directory rather than a single file.)

thanks for pointing this out. will fix it.

"Iterate over Expression in for Loop"

this might be difficult to do with the hint files. But NB has a template which comes really close to what you want. type for + ctrl+space, then select the for loop you want, then paste the expression into the selected iterable field (or call a method etc) - this should update the rest.

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

@mbien Oh, that works! I learned a new NetBeans feature today...

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

I think this PR is now ready to merge, if you approve. (I already merged #8109 now, which was the first half of this work.)

This is a follow-up on apache#8114 and apache#8109 . To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.
This PR, combined with the previously mentioned PRs, handles most of the remaining cases.
Specifically:
* Search for 'new ImageIcon(' and rewrite each case to use ImageUtilities to load icons instead.
* Search for 'instanceof ImageIcon' and generalize to 'instanceof Icon' when appropriate.
* Search for 'getLookAndFeel*getDisabledIcon' and switch to ImageUtilities.createDisabledIcon.
…orms that were constructed with the Matisse form builder.
(To render at full HiDPI resolution, Icon/Image instances must be created via the methods in ImageUtilities rather than, in particular, the constructors of ImageIcon.)
These cases were put in a separate commit since they involved re-generation of auto-generated code. To keep the patch simple, I excluded some reformatting of unrelated code that Matisse did when regenerating initComponents().

@mbienmbien left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure I reviewed this. Must have forgotten to hit approve. Thanks for the cleanups!

@eirikbakke

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you! Merging.

@eirikbakke
eirikbakke merged commit c01cb45 into apache:masterFeb 24, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all-tests[ci] enable all testsci:dev-build[ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page)Code cleanupLabel for cleanup done on the Netbeans IDEPlatform[ci] enable platform tests (platform/*)UIUser Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@eirikbakke@mbien@matthiasblaesing@neilcsmith-net