mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
support multi-resolution images in disabled icons on Java 9+ (e.g. @2x icons on macOS) (issue #70)
This commit is contained in:
@@ -23,6 +23,11 @@ plugins {
|
|||||||
|
|
||||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
create( "java9" ) {
|
||||||
|
java {
|
||||||
|
setSrcDirs( listOf( "src/main/java9" ) )
|
||||||
|
}
|
||||||
|
}
|
||||||
create( "module-info" ) {
|
create( "module-info" ) {
|
||||||
java {
|
java {
|
||||||
// include "src/main/java" here to get compile errors if classes are
|
// include "src/main/java" here to get compile errors if classes are
|
||||||
@@ -52,6 +57,12 @@ tasks {
|
|||||||
archiveBaseName.set( "flatlaf" )
|
archiveBaseName.set( "flatlaf" )
|
||||||
|
|
||||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||||
|
manifest.attributes( "Multi-Release" to "true" )
|
||||||
|
|
||||||
|
into( "META-INF/versions/9" ) {
|
||||||
|
from( sourceSets["java9"].output )
|
||||||
|
}
|
||||||
|
|
||||||
from( sourceSets["module-info"].output ) {
|
from( sourceSets["module-info"].output ) {
|
||||||
include( "module-info.class" )
|
include( "module-info.class" )
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import java.util.Map;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
@@ -64,6 +65,7 @@ import javax.swing.plaf.basic.BasicLookAndFeel;
|
|||||||
import javax.swing.text.StyleContext;
|
import javax.swing.text.StyleContext;
|
||||||
import javax.swing.text.html.HTMLEditorKit;
|
import javax.swing.text.html.HTMLEditorKit;
|
||||||
import com.formdev.flatlaf.util.GrayFilter;
|
import com.formdev.flatlaf.util.GrayFilter;
|
||||||
|
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
@@ -136,9 +138,14 @@ public abstract class FlatLaf
|
|||||||
: new GrayFilter( 25, -25, 100 );
|
: new GrayFilter( 25, -25, 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageFilter filter = (ImageFilter) grayFilter;
|
||||||
|
Function<Image, Image> mapper = img -> {
|
||||||
|
ImageProducer producer = new FilteredImageSource( img.getSource(), filter );
|
||||||
|
return Toolkit.getDefaultToolkit().createImage( producer );
|
||||||
|
};
|
||||||
|
|
||||||
Image image = ((ImageIcon)icon).getImage();
|
Image image = ((ImageIcon)icon).getImage();
|
||||||
ImageProducer producer = new FilteredImageSource( image.getSource(), (ImageFilter) grayFilter );
|
return new ImageIconUIResource( MultiResolutionImageSupport.map( image, mapper ) );
|
||||||
return new ImageIconUIResource( Toolkit.getDefaultToolkit().createImage( producer ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for multi-resolution images available since Java 9.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class MultiResolutionImageSupport
|
||||||
|
{
|
||||||
|
public static boolean isAvailable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMultiResolutionImage( Image image ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image create( int baseImageIndex, Image... resolutionVariants ) {
|
||||||
|
return resolutionVariants[baseImageIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image map( Image image, Function<Image, Image> mapper ) {
|
||||||
|
return mapper.apply( image );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.image.AbstractMultiResolutionImage;
|
||||||
|
import java.awt.image.BaseMultiResolutionImage;
|
||||||
|
import java.awt.image.MultiResolutionImage;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for multi-resolution images available since Java 9.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class MultiResolutionImageSupport
|
||||||
|
{
|
||||||
|
public static boolean isAvailable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMultiResolutionImage( Image image ) {
|
||||||
|
return image instanceof MultiResolutionImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image create( int baseImageIndex, Image... resolutionVariants ) {
|
||||||
|
return new BaseMultiResolutionImage( baseImageIndex, resolutionVariants );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image map( Image image, Function<Image, Image> mapper ) {
|
||||||
|
return image instanceof MultiResolutionImage
|
||||||
|
? new MappedMultiResolutionImage( image, mapper )
|
||||||
|
: mapper.apply( image );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class MappedMultiResolutionImage -----------------------------------
|
||||||
|
|
||||||
|
private static class MappedMultiResolutionImage
|
||||||
|
extends AbstractMultiResolutionImage
|
||||||
|
{
|
||||||
|
private final Image mrImage;
|
||||||
|
private final Function<Image, Image> mapper;
|
||||||
|
private final IdentityHashMap<Image, Image> cache = new IdentityHashMap<>();
|
||||||
|
|
||||||
|
MappedMultiResolutionImage( Image mrImage, Function<Image, Image> mapper ) {
|
||||||
|
assert mrImage instanceof MultiResolutionImage;
|
||||||
|
|
||||||
|
this.mrImage = mrImage;
|
||||||
|
this.mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image getResolutionVariant( double destImageWidth, double destImageHeight ) {
|
||||||
|
Image variant = ((MultiResolutionImage)mrImage).getResolutionVariant( destImageWidth, destImageHeight );
|
||||||
|
return mapAndCacheImage( variant );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Image> getResolutionVariants() {
|
||||||
|
List<Image> variants = ((MultiResolutionImage)mrImage).getResolutionVariants();
|
||||||
|
List<Image> mappedVariants = new ArrayList<>();
|
||||||
|
for( Image image : variants )
|
||||||
|
mappedVariants.add( mapAndCacheImage( image ) );
|
||||||
|
return mappedVariants;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Image getBaseImage() {
|
||||||
|
return mapAndCacheImage( mrImage );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image mapAndCacheImage( Image image ) {
|
||||||
|
return cache.computeIfAbsent( image, img -> {
|
||||||
|
return new ImageIcon( mapper.apply( img ) ).getImage();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,9 @@ tasks {
|
|||||||
|
|
||||||
manifest {
|
manifest {
|
||||||
attributes( "Main-Class" to "com.formdev.flatlaf.demo.FlatLafDemo" )
|
attributes( "Main-Class" to "com.formdev.flatlaf.demo.FlatLafDemo" )
|
||||||
|
|
||||||
|
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 )
|
||||||
|
attributes( "Multi-Release" to "true" )
|
||||||
}
|
}
|
||||||
|
|
||||||
exclude( "module-info.class" )
|
exclude( "module-info.class" )
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ class MoreComponentsPanel
|
|||||||
JButton button7 = new JButton();
|
JButton button7 = new JButton();
|
||||||
JButton button8 = new JButton();
|
JButton button8 = new JButton();
|
||||||
JToggleButton toggleButton6 = new JToggleButton();
|
JToggleButton toggleButton6 = new JToggleButton();
|
||||||
|
JButton button1 = new JButton();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
setLayout(new MigLayout(
|
setLayout(new MigLayout(
|
||||||
@@ -380,6 +381,11 @@ class MoreComponentsPanel
|
|||||||
toggleButton6.setIcon(UIManager.getIcon("Tree.leafIcon"));
|
toggleButton6.setIcon(UIManager.getIcon("Tree.leafIcon"));
|
||||||
toggleButton6.setSelected(true);
|
toggleButton6.setSelected(true);
|
||||||
toolBar1.add(toggleButton6);
|
toolBar1.add(toggleButton6);
|
||||||
|
|
||||||
|
//---- button1 ----
|
||||||
|
button1.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/demo/icons/intellij-showWriteAccess.png")));
|
||||||
|
button1.setEnabled(false);
|
||||||
|
toolBar1.add(button1);
|
||||||
}
|
}
|
||||||
add(toolBar1, "cell 1 10 3 1,growx");
|
add(toolBar1, "cell 1 10 3 1,growx");
|
||||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8"
|
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -355,6 +355,11 @@ new FormModel {
|
|||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.leafIcon" )
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "Tree.leafIcon" )
|
||||||
"selected": true
|
"selected": true
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "button1"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/intellij-showWriteAccess.png" )
|
||||||
|
"enabled": false
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 10 3 1,growx"
|
"value": "cell 1 10 3 1,growx"
|
||||||
} )
|
} )
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 325 B |
Binary file not shown.
|
After Width: | Height: | Size: 495 B |
@@ -27,8 +27,11 @@ import java.awt.image.FilteredImageSource;
|
|||||||
import java.awt.image.ImageProducer;
|
import java.awt.image.ImageProducer;
|
||||||
import java.awt.image.RGBImageFilter;
|
import java.awt.image.RGBImageFilter;
|
||||||
import java.beans.*;
|
import java.beans.*;
|
||||||
|
import java.net.URL;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
@@ -575,8 +578,23 @@ public class FlatDisabledIconsTest
|
|||||||
private final ImageIcon darkIcon;
|
private final ImageIcon darkIcon;
|
||||||
|
|
||||||
LightOrDarkIcon( String lightIconName, String darkIconName ) {
|
LightOrDarkIcon( String lightIconName, String darkIconName ) {
|
||||||
this.lightIcon = new ImageIcon( getClass().getResource( lightIconName ) );
|
this.lightIcon = loadIcon( lightIconName );
|
||||||
this.darkIcon = new ImageIcon( getClass().getResource( darkIconName ) );
|
this.darkIcon = loadIcon( darkIconName );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImageIcon loadIcon( String iconName ) {
|
||||||
|
ImageIcon icon = new ImageIcon( LightOrDarkIcon.class.getResource( iconName ) );
|
||||||
|
|
||||||
|
if( SystemInfo.IS_MAC || !MultiResolutionImageSupport.isAvailable() || !iconName.endsWith( ".png" ) )
|
||||||
|
return icon;
|
||||||
|
|
||||||
|
String iconName2x = iconName.replace( ".png", "@2x.png" );
|
||||||
|
URL url2x = LightOrDarkIcon.class.getResource( iconName2x );
|
||||||
|
if( url2x == null )
|
||||||
|
return icon;
|
||||||
|
|
||||||
|
ImageIcon icon2x = new ImageIcon( url2x );
|
||||||
|
return new ImageIcon( MultiResolutionImageSupport.create( 0, icon.getImage(), icon2x.getImage() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageIcon getCurrentIcon() {
|
private ImageIcon getCurrentIcon() {
|
||||||
|
|||||||
Reference in New Issue
Block a user