Dave Jarvis' Repositories

git clone /repo/kmcaster.git

Micro performance optimizations

Author DaveJarvis <email>
Date 2020-07-26 01:29:31 GMT-0700
Commit 77d0366113dec18f052ea3480f91c82807a11535
Parent 30d2436
Delta 51 lines added, 64 lines removed, 13-line decrease
src/main/com/whitemagicsoftware/kmcaster/EventHandler.java
protected void updateSwitchLabel( final HardwareSwitchState state ) {
final var keyColour = KEY_COLOURS.get( state.getHardwareState() );
- final var pressed = state.isHardwareState( SWITCH_PRESSED );
if( state.isModifier() ) {
updateLabel( state, keyColour );
- if( pressed ) {
- mKeyCounter.reset();
- }
+ mKeyCounter.reset();
}
else {
final var component = getHardwareComponent( state );
final var keyValue = state.getValue();
// A non-modifier key has been pressed.
- if( pressed ) {
+ if( state.isHardwareState( SWITCH_PRESSED ) ) {
// Determine whether there are separate parts for the key label.
final var index = keyValue.indexOf( ' ' );
final var supSize = compDimen.scale( .6f );
final var mainSize = compDimen.scale( .9f );
-
- final var s = new String[]{
- keyValue.substring( 0, index ),
- keyValue.substring( index + 1 )
- };
// Label for "Num", "Back", "Tab", and other dual-labelled keys.
- final var sup = new AutofitLabel( s[ 0 ], LABEL_FONT );
+ final var sup = new AutofitLabel(
+ keyValue.substring( 0, index ), LABEL_FONT );
sup.setVisible( false );
sup.setForeground( keyColour );
sup.setVerticalAlignment( TOP );
// Label for number pad keys or icon glyphs.
- final var main = new AutofitLabel( s[ 1 ], LABEL_FONT );
+ final var main = new AutofitLabel(
+ keyValue.substring( index + 1 ), LABEL_FONT );
main.setVisible( false );
main.setForeground( keyColour );
main.setHorizontalAlignment( CENTER );
- main.setVerticalAlignment( CENTER );
// Keep removeAll/add operations close together to minimize flicker.
src/main/com/whitemagicsoftware/kmcaster/HardwareComponent.java
private final Insets mInsets;
+ private Dimension mPreferredSize;
+
/**
* Constructs a new {@link HardwareComponent} without an initial state. The
@Override
public Dimension getPreferredSize() {
- // Race-condition guard.
- final var image = getActiveImage();
-
- return new Dimension(
- image.getWidth( null ), image.getHeight( null )
- );
+ return mPreferredSize == null
+ ? mPreferredSize = calcPreferredSize()
+ : mPreferredSize;
}
repaint();
}
- }
-
- private Image getActiveImage() {
- return getStateImages().get( getState() );
}
public S getState() {
return mState;
+ }
+
+ private Dimension calcPreferredSize() {
+ // Race-condition guard.
+ final var image = getActiveImage();
+
+ return new Dimension(
+ image.getWidth( null ), image.getHeight( null )
+ );
+ }
+
+ private Image getActiveImage() {
+ return getStateImages().get( getState() );
}
src/main/com/whitemagicsoftware/kmcaster/listeners/KeyboardListener.java
import static java.util.Map.entry;
import static java.util.Optional.ofNullable;
+import static javax.swing.SwingUtilities.invokeLater;
import static org.jnativehook.keyboard.NativeKeyEvent.getKeyText;
}
- updateRegular( mRegularHeld, getDisplayText( e ) );
+ invokeLater(
+ () -> updateRegular( mRegularHeld, getDisplayText( e ) )
+ );
} );
}
() -> {
final var timer = delayedAction( mDelayRegular, ( action ) ->
- updateRegular( getDisplayText( e ), "" )
+ invokeLater(
+ () -> updateRegular( getDisplayText( e ), "" )
+ )
);
src/main/com/whitemagicsoftware/kmcaster/ui/AutofitLabel.java
import javax.swing.*;
import java.awt.*;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextLayout;
import static java.awt.event.HierarchyEvent.PARENT_CHANGED;
*/
private Font computeScaledFont() {
- final var frc = getFontRenderContext();
final var text = getText();
+ final var graphics = getGraphics();
final var dstWidthPx = getWidth();
final var dstHeightPx = getHeight();
- var minSizePt = 1f;
- var maxSizePt = 100f;
+ var minSizePt = 1;
+ var maxSizePt = 100;
var scaledFont = getFont();
- float scaledPt = scaledFont.getSize();
-
- // TextLayout cannot suffer null or empty values, so return the default
- // font size if the label is cleared out.
- if( text != null && !text.isEmpty() ) {
- while( maxSizePt - minSizePt > 1f ) {
- scaledFont = scaledFont.deriveFont( scaledPt );
+ var scaledPt = scaledFont.getSize();
- final var layout = new TextLayout( text, scaledFont, frc );
- final var metrics = scaledFont.getLineMetrics( text, frc );
- final var fontWidthPx = layout.getVisibleAdvance();
- final var fontHeightPx = metrics.getHeight();
+ while( maxSizePt - minSizePt > 1 ) {
+ scaledFont = scaledFont.deriveFont( (float) scaledPt );
- if( (fontWidthPx > dstWidthPx) || (fontHeightPx > dstHeightPx) ) {
- maxSizePt = scaledPt;
- }
- else {
- minSizePt = scaledPt;
- }
+ final var fm = getFontMetrics( scaledFont );
+ final var bounds = fm.getStringBounds( text, graphics );
+ final var fontWidthPx = (int) bounds.getWidth();
+ final var fontHeightPx = (int) bounds.getHeight();
- scaledPt = (minSizePt + maxSizePt) / 2;
+ if( (fontWidthPx > dstWidthPx) || (fontHeightPx > dstHeightPx) ) {
+ maxSizePt = scaledPt;
+ }
+ else {
+ minSizePt = scaledPt;
}
+
+ scaledPt = (minSizePt + maxSizePt) / 2;
}
// Round down to guarantee fit.
return scaledFont.deriveFont( (float) floor( scaledPt ) );
- }
-
- /**
- * Gets the {@link FontRenderContext} for the parent {@link Container}'s
- * {@link Graphics} context, casting it to a {@link Graphics2D} context.
- *
- * @return The parent's {@link Graphics2D} context.
- */
- private FontRenderContext getFontRenderContext() {
- return ((Graphics2D) getGraphics()).getFontRenderContext();
}
}
src/main/com/whitemagicsoftware/kmcaster/ui/BoundsCalculator.java
/**
- * Returns the total width and height of an area that is safe for
- * writing on the {@link Container} parameter provided during construction.
+ * Returns the safe area for writing on the {@link Container} parameter
+ * provided during construction.
*
* @return The {@link Container}'s safe area, based on the
src/main/com/whitemagicsoftware/kmcaster/ui/ScalableDimension.java
*/
public Dimension scale( final Dimension dst ) {
- assert dst != null;
-
// Determine the ratio that has the best fit, then scale both dimensions
// with respect to said ratio.
*/
public Dimension scale( final double factor ) {
- assert factor >= 0;
-
return new ScalableDimension(
getWidth() * factor, getHeight() * factor
src/main/com/whitemagicsoftware/kmcaster/util/ConsecutiveEventCounter.java
public void reset() {
mCount = 1;
+ mPrevious = null;
}