wrps-demo-kit/99-reference/ciserver-hmi-deployment/components/ExtendedJBorder.java
Clio Liu 4fc5f80b21 chore: preserve reference files byte-for-byte
.gitattributes normalised the CI Server exports under 99-reference/ to LF.
They are a format specification and must match what CI Server actually
wrote, so mark the folder -text and restore the originals.
2026-09-02 15:17:49 +10:00

203 lines
7.1 KiB
Java

/*-
* @(#)ExtendedJBorder.java
*
* Copyright: Yokogawa, All rights reserved.
* YOKOGAWA PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
* Author: C. Horevoorts
*
* ----------------------------------------------------------------------------
* Changes ....
* ----------------------------------------------------------------------------
* Who When Change What
* ----------------------------------------------------------------------------
* HVS Feb-08 e9435 First version documented
* BNL Apr-09 i10199 Correct hit detection for border top, bottom and text
* BNL Mar-11 e10468 732 Correct hit detection for empty border with text
* HVS Jun-20 e12272 Port to JViews 2017.2
*
*/
package fasttools.jwui.ilv.graphic;
import fasttools.jwui.common.property.JBorderType;
import fasttools.jwui.ilv.swing.INonRectangularJComponent;
import fasttools.jwui.ilv.swing.IJComponentTagger;
import ilog.views.IlvPoint;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* Extends the ExtendedJBorder to be usable in the {@link ExtendedJComponent} container.
*/
public class ExtendedJBorder extends JPanel implements IJComponentTagger, INonRectangularJComponent {
private String cLabel = "";
private Border cBorder = JBorderType.NATIVE_BORDER;
public ExtendedJBorder() {
setOpaque(false);
setBorder(cBorder);
}
/**
* Sets the label.
*
* @param label The label
*/
public void setLabelText(String label) {
if (label == null) {
label = "";
}
if (!cLabel.equals(label)) {
cLabel = label;
createBorder();
}
}
/**
* Returns the label.
*
* @return The label
*/
public String getLabelText() {
return cLabel;
}
/**
* Sets the border type.
*
* @param borderType The border type
*/
public void setBorderType(JBorderType borderType) {
Border mBorder = borderType.getBorder();
if (mBorder != cBorder) {
cBorder = mBorder;
createBorder();
}
}
/**
* Returns the border type.
*
* @return The border type
*/
public JBorderType getBorderType() {
return new JBorderType(cBorder);
}
/**
* Override to update the border.
*
* @param color The color
*/
public void setForeground(Color color) {
super.setForeground(color);
createBorder();
}
/**
* Override to update the border.
*
* @param font The font
*/
public void setFont(Font font) {
super.setFont(font);
createBorder();
}
/**
* Recreate the border.
*/
private void createBorder() {
if (cLabel != null) {
Border mBorder = cBorder;
if (mBorder instanceof LineBorder) {
mBorder = new LineBorder(getForeground());
}
if (cLabel.length() > 0) {
mBorder = new TitledBorder(mBorder, cLabel, TitledBorder.LEADING, TitledBorder.TOP, getFont(), getForeground());
}
setBorder(mBorder);
}
}
public boolean contains(Point2D p, AffineTransform t, GraphicHelper graphicHelper, float zoomFactor, boolean zoomEnabled) {
// TODO: Shearing is not taken into consideration, so sheared borders won't hit-detect correctly.
Shape mShape = graphicHelper.getShape();
if (isOpaque()) {
return mShape.contains(p);
}
if (!mShape.contains(p)) {
return false;
}
Point2D mTopLeft = graphicHelper.getXYNull();
Point2D mTopRight = graphicHelper.getXYWidth();
double mRotation = GraphicHelper.getRotationAngleInDegrees((IlvPoint) mTopLeft, (IlvPoint) mTopRight);
String mLabel = getLabelText();
if (mLabel != null && !mLabel.equals("")) {
Graphics2D g = (Graphics2D) getGraphics();
FontRenderContext mFontRenderingContext = g.getFontRenderContext();
Font mFont = getFont();
TextLayout mActualText = new TextLayout(mLabel, mFont, mFontRenderingContext);
TextLayout mHeightText = new TextLayout("abcdefghijklmnopqrstuvwxyz", mFont, mFontRenderingContext);
Rectangle2D mBounds = mActualText.getBounds();
Rectangle2D mHeightBounds = mHeightText.getBounds();
double mZoomFactor = zoomFactor / (zoomEnabled ? 1.0 : t.getScaleX());
double mTextHeight = mHeightBounds.getHeight() * mZoomFactor;
// NOTE: The width in mBounds is too long for reasons that I've given up trying to figure out. Multiplying by 0.75 gives us a value that's good enough for now.
double mTextWidth = mBounds.getWidth() * mZoomFactor * 0.75;
double mLeftInset = 5.0 * mZoomFactor;
Point2D mTextTopLeft = getPointFrom((IlvPoint) mTopLeft, mLeftInset, mRotation);
Point2D mTextTopRight = getPointFrom((IlvPoint) mTextTopLeft, mTextWidth, mRotation);
Point2D mTextBottomLeft = getPointFrom((IlvPoint) mTextTopLeft, mTextHeight, mRotation + 90.0);
Point2D mTextBottomRight = getPointFrom((IlvPoint) mTextBottomLeft, mTextWidth, mRotation);
Path2D.Double mTextShapeRectangle = new Path2D.Double(Path2D.WIND_NON_ZERO, 4);
mTextShapeRectangle.moveTo(mTextTopLeft.getX(), mTextTopLeft.getY());
mTextShapeRectangle.lineTo(mTextTopRight.getX(), mTextTopRight.getY());
mTextShapeRectangle.lineTo(mTextBottomRight.getX(), mTextBottomRight.getY());
mTextShapeRectangle.lineTo(mTextBottomLeft.getX(), mTextBottomLeft.getY());
if (mTextShapeRectangle.contains(p)) {
return true;
}
}
if (!getBorderType().equals(new JBorderType(JBorderType.EMPTY))) {
double mBorderWidth = 6.0 * zoomFactor;
if (!zoomEnabled && t != null) {
mBorderWidth /= t.getScaleX();
}
Point2D mBottomLeft = graphicHelper.getXYHeight();
Point2D mBottomRight = graphicHelper.getXYWidthHeight();
mTopLeft = getPointFrom((IlvPoint) mTopLeft, mBorderWidth, mRotation + 45.0);
mTopRight = getPointFrom((IlvPoint) mTopRight, mBorderWidth, mRotation + 135.0);
mBottomRight = getPointFrom((IlvPoint) mBottomRight, mBorderWidth, mRotation + 225.0);
mBottomLeft = getPointFrom((IlvPoint) mBottomLeft, mBorderWidth, mRotation + 315.0);
Path2D.Double mInsideShape = new Path2D.Double(Path2D.WIND_NON_ZERO, 4);
mInsideShape.moveTo(mTopLeft.getX(), mTopLeft.getY());
mInsideShape.lineTo(mTopRight.getX(), mTopRight.getY());
mInsideShape.lineTo(mBottomRight.getX(), mBottomRight.getY());
mInsideShape.lineTo(mBottomLeft.getX(), mBottomLeft.getY());
if (!mInsideShape.contains(p)) {
return true;
}
}
return false;
}
private Point2D getPointFrom(IlvPoint point, double distance, double angle) {
IlvPoint mMidPoint = GraphicHelper.getPointRotatedFrom(point, angle - 45.0, distance);
return GraphicHelper.getPointRotatedFrom(mMidPoint, angle + 45.0, distance);
}
}