1420 lines
37 KiB
Java
1420 lines
37 KiB
Java
|
|
/*
|
||
|
|
Copyright 2007 Infordata S.p.A.
|
||
|
|
|
||
|
|
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
|
||
|
|
|
||
|
|
http://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.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
!!V 10/04/97 rel. 0.93 - some fixes to add SignedNumeric fields handling.
|
||
|
|
16/04/97 rel. 0.94 - userError method added.
|
||
|
|
08/05/97 rel. 0.95b-
|
||
|
|
27/05/97 rel. 1.00 - first release.
|
||
|
|
25/07/97 rel. 1.03a- a bug in ...Multicaster.
|
||
|
|
06/08/97 rel. 1.03c- bug fix.
|
||
|
|
27/08/97 rel. 1.04 - clipboard support.
|
||
|
|
03/03/98 rel. _.___- SWING and reorganization.
|
||
|
|
***
|
||
|
|
30/06/98 rel. _.___- Swing, JBuilder2 e VSS.
|
||
|
|
29/07/99 rel. 1.14 - Rework on 3d look&feel.
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
package net.infordata.em.crt5250;
|
||
|
|
|
||
|
|
|
||
|
|
import java.awt.AWTEventMulticaster;
|
||
|
|
import java.awt.Color;
|
||
|
|
import java.awt.Dimension;
|
||
|
|
import java.awt.Graphics;
|
||
|
|
import java.awt.Rectangle;
|
||
|
|
import java.awt.event.KeyEvent;
|
||
|
|
import java.io.IOException;
|
||
|
|
import java.util.EventListener;
|
||
|
|
|
||
|
|
import net.infordata.em.tnprot.XITelnet;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Implements behaviour of 5250 fields with some extensions.
|
||
|
|
*
|
||
|
|
* @version
|
||
|
|
* @author Valentino Proietti - Infordata S.p.A.
|
||
|
|
*/
|
||
|
|
public class XI5250Field implements XI5250BaseField {
|
||
|
|
|
||
|
|
//!!0.95b border styles
|
||
|
|
/**
|
||
|
|
* Uses default border definition.
|
||
|
|
* @see #setBorderStyle
|
||
|
|
* @see XI5250Crt#setDefFieldsBorderStyle
|
||
|
|
*/
|
||
|
|
public static final int DEFAULT_BORDER = 0;
|
||
|
|
/**
|
||
|
|
* No border.
|
||
|
|
* @see #setBorderStyle
|
||
|
|
* @see XI5250Crt#setDefFieldsBorderStyle
|
||
|
|
*/
|
||
|
|
public static final int NO_BORDER = 1;
|
||
|
|
/**
|
||
|
|
* Raised border.
|
||
|
|
* @see #setBorderStyle
|
||
|
|
* @see XI5250Crt#setDefFieldsBorderStyle
|
||
|
|
*/
|
||
|
|
public static final int RAISED_BORDER = 2;
|
||
|
|
/**
|
||
|
|
* Lowered border.
|
||
|
|
* @see #setBorderStyle
|
||
|
|
* @see XI5250Crt#setDefFieldsBorderStyle
|
||
|
|
*/
|
||
|
|
public static final int LOWERED_BORDER = 3;
|
||
|
|
|
||
|
|
private XI5250Crt ivCrt;
|
||
|
|
private byte[] ivFFW;
|
||
|
|
private byte[] ivFCW;
|
||
|
|
private int ivCol;
|
||
|
|
private int ivRow;
|
||
|
|
|
||
|
|
//!!0.95b ivInputLen rapresent the length of the input area
|
||
|
|
private int ivInputLen;
|
||
|
|
//!!0.95b this is the real field length
|
||
|
|
private int ivLength;
|
||
|
|
|
||
|
|
private int ivAttr;
|
||
|
|
|
||
|
|
// valid only after updateStr() call
|
||
|
|
private String ivStr;
|
||
|
|
private int ivFldPos;
|
||
|
|
private int ivCurPos;
|
||
|
|
private int ivPos;
|
||
|
|
|
||
|
|
//!!0.95
|
||
|
|
private XI5250FieldListener ivFieldListener;
|
||
|
|
private XI5250FieldPaintListener ivFieldPaintListener;
|
||
|
|
|
||
|
|
private boolean ivEnabled = true;
|
||
|
|
|
||
|
|
//!!0.95b
|
||
|
|
private int ivBorderStyle = DEFAULT_BORDER;
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param aCrt the containing XI5250Crt
|
||
|
|
* @param aCol the field position
|
||
|
|
* @param aRow the field position
|
||
|
|
* @param aLen the field length
|
||
|
|
* @param aAttr the field color attribute
|
||
|
|
*/
|
||
|
|
public XI5250Field(XI5250Crt aCrt, int aCol, int aRow, int aLen, int aAttr) {
|
||
|
|
this(aCrt, new byte[2], new byte[2], aCol, aRow, aLen, aAttr);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param aCrt the containing XI5250Crt
|
||
|
|
* @param aFFW see IBM 5250 function reference manual page 2-68
|
||
|
|
* @param aFCW see IBM 5250 function reference manual page 2-65
|
||
|
|
* @param aCol the field position
|
||
|
|
* @param aRow the field position
|
||
|
|
* @param aLen the field length
|
||
|
|
* @param aAttr the field color attribute
|
||
|
|
*/
|
||
|
|
public XI5250Field(XI5250Crt aCrt, byte[] aFFW, byte[] aFCW,
|
||
|
|
int aCol, int aRow, int aLen, int aAttr) {
|
||
|
|
ivCrt = aCrt;
|
||
|
|
ivFFW = aFFW;
|
||
|
|
ivFCW = aFCW;
|
||
|
|
ivCol = aCol;
|
||
|
|
ivRow = aRow;
|
||
|
|
ivInputLen = aLen;
|
||
|
|
ivLength = aLen;
|
||
|
|
ivAttr = aAttr;
|
||
|
|
|
||
|
|
if (isSignedNumeric())
|
||
|
|
--ivInputLen;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected void removeNotify() {
|
||
|
|
//!!V never ivCrt = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* XI5250FieldListener handling
|
||
|
|
*/
|
||
|
|
public synchronized void addFieldListener(XI5250FieldListener l) {
|
||
|
|
ivFieldListener = (XI5250FieldListener)Multicaster.add(ivFieldListener, l);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* XI5250FieldListener handling
|
||
|
|
*/
|
||
|
|
public synchronized void removeFieldListener(XI5250FieldListener l) {
|
||
|
|
ivFieldListener = (XI5250FieldListener)Multicaster.
|
||
|
|
remove(ivFieldListener, l);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Routes XI5250FieldEvent to listeners
|
||
|
|
*/
|
||
|
|
protected void processFieldEvent(XI5250FieldEvent e) {
|
||
|
|
if (ivFieldListener == null)
|
||
|
|
return;
|
||
|
|
|
||
|
|
switch (e.getID()) {
|
||
|
|
//
|
||
|
|
case XI5250FieldEvent.ACTIVATED:
|
||
|
|
ivFieldListener.activated(e);
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case XI5250FieldEvent.DEACTIVATED:
|
||
|
|
ivFieldListener.deactivated(e);
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case XI5250FieldEvent.VALUE_CHANGED:
|
||
|
|
ivFieldListener.valueChanged(e);
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case XI5250FieldEvent.ENABLED_STATE_CHANGED:
|
||
|
|
ivFieldListener.enabledStateChanged(e);
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case XI5250FieldEvent.KEY_EVENT:
|
||
|
|
ivFieldListener.keyEvent(e);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* XI5250FieldPaintListener handling
|
||
|
|
*/
|
||
|
|
public synchronized void addFieldPaintListener(XI5250FieldPaintListener l) {
|
||
|
|
ivFieldPaintListener =
|
||
|
|
(XI5250FieldPaintListener)Multicaster.
|
||
|
|
add(ivFieldPaintListener, l);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* XI5250FieldPaintListener handling
|
||
|
|
*/
|
||
|
|
public synchronized void removeFieldPaintListener(XI5250FieldPaintListener l) {
|
||
|
|
ivFieldPaintListener =
|
||
|
|
(XI5250FieldPaintListener)Multicaster.
|
||
|
|
remove(ivFieldPaintListener, l);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* routes XI5250FieldPaintEvent to listeners
|
||
|
|
*/
|
||
|
|
protected void processFieldPaintEvent(XI5250FieldPaintEvent e) {
|
||
|
|
if (ivFieldPaintListener == null)
|
||
|
|
return;
|
||
|
|
|
||
|
|
switch (e.getID()) {
|
||
|
|
//
|
||
|
|
case XI5250FieldPaintEvent.FIELD_PAINT:
|
||
|
|
ivFieldPaintListener.fieldPaint(e);
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case XI5250FieldPaintEvent.ROW_PAINT:
|
||
|
|
ivFieldPaintListener.rowPaint(e);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public final XI5250Crt getCrt() {
|
||
|
|
return ivCrt;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Initializes the field.
|
||
|
|
* It is called after that the 5250 panel construction has ended to let the field
|
||
|
|
* refresh its color attribute.
|
||
|
|
*/
|
||
|
|
public void init() {
|
||
|
|
updateStr();
|
||
|
|
|
||
|
|
// Is color attribute changed ?
|
||
|
|
int newAttr = ivCrt.getAttr(ivCrt.toColPos(ivFldPos - 1), ivCrt.toRowPos(ivFldPos - 1));
|
||
|
|
if (newAttr != ivAttr) {
|
||
|
|
ivAttr = newAttr;
|
||
|
|
String str = getString();
|
||
|
|
int from = 0;
|
||
|
|
while (true) {
|
||
|
|
int idx = str.indexOf(XI5250Crt.ATTRIBUTE_PLACE_HOLDER, from);
|
||
|
|
if (idx < 0) {
|
||
|
|
ivCrt.drawString(str.substring(from),
|
||
|
|
ivCrt.toColPos(ivFldPos + from), ivCrt.toRowPos(ivFldPos + from), newAttr);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
ivCrt.drawString(str.substring(from, idx),
|
||
|
|
ivCrt.toColPos(ivFldPos + from), ivCrt.toRowPos(ivFldPos + from), newAttr);
|
||
|
|
newAttr = ivCrt.getAttr(ivCrt.toColPos(ivFldPos + idx), ivCrt.toRowPos(ivFldPos + idx));
|
||
|
|
ivCrt.drawString(String.valueOf(XI5250Crt.ATTRIBUTE_PLACE_HOLDER),
|
||
|
|
ivCrt.toColPos(ivFldPos + idx), ivCrt.toRowPos(ivFldPos + idx), newAttr);
|
||
|
|
from = idx + 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used for example to write field contents to the 5250 stream.
|
||
|
|
* If needed some internal attribute can be exposed.
|
||
|
|
*/
|
||
|
|
public void saveTo(XI5250FieldSaver aSaver) throws IOException {
|
||
|
|
// no getTrimmedString()
|
||
|
|
aSaver.write(this, getString());
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Clear field to nulls.
|
||
|
|
*/
|
||
|
|
public void clear() {
|
||
|
|
char[] chs = new char[ivLength];
|
||
|
|
for (int i = 0; i < chs.length; i++)
|
||
|
|
chs[i] = '\u0000';
|
||
|
|
ivCrt.drawString(new String(chs), ivCol, ivRow, XI5250Crt.USE_PRESENT_ATTRIBUTE);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Changes the field contents.
|
||
|
|
*/
|
||
|
|
public void setString(String aStr) {
|
||
|
|
if (aStr == getTrimmedString())
|
||
|
|
return;
|
||
|
|
|
||
|
|
/* !!1.04e
|
||
|
|
ivCrt.drawString(aStr, ivCol, ivRow, XI5250Crt.USE_PRESENT_ATTRIBUTE);
|
||
|
|
setMDTOn();
|
||
|
|
*/
|
||
|
|
|
||
|
|
int s = ivCrt.toLinearPos(ivCol, ivRow);
|
||
|
|
char ch;
|
||
|
|
int col, row;
|
||
|
|
for (int i = 0; i < aStr.length() && i < ivInputLen; i++) {
|
||
|
|
ch = aStr.charAt(i);
|
||
|
|
col = ivCrt.toColPos(s + i);
|
||
|
|
row = ivCrt.toRowPos(s + i);
|
||
|
|
insertChar(ch, col, row, false, false);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns value of the field as String.
|
||
|
|
* NOTE: signed numeric are followed by sign char
|
||
|
|
*/
|
||
|
|
public String getString() {
|
||
|
|
String str = ivCrt.getString(ivCol, ivRow, ivLength);
|
||
|
|
|
||
|
|
return str;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns value of the field as String, all trailing nulls and blankes are cutted off.
|
||
|
|
* NOTE: signed numeric are followed by sign char
|
||
|
|
*/
|
||
|
|
public String getTrimmedString() {
|
||
|
|
String str = getString();
|
||
|
|
int i;
|
||
|
|
|
||
|
|
// exclude trailing null and blank chars
|
||
|
|
for (i = str.length() - 1; (i >= 0) && ((str.charAt(i) == '\u0000') ||
|
||
|
|
(str.charAt(i) == ' ')); i--)
|
||
|
|
;
|
||
|
|
|
||
|
|
return (i < 0) ? "" : str.substring(0, i + 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the Field Format Word.
|
||
|
|
*/
|
||
|
|
public byte getFFW(int i) {
|
||
|
|
return ivFFW[i];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the Field Control Word.
|
||
|
|
*/
|
||
|
|
public byte getFCW(int i) {
|
||
|
|
return ivFCW[i];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The field column position.
|
||
|
|
*/
|
||
|
|
public int getCol() {
|
||
|
|
return ivCol;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The field row position.
|
||
|
|
*/
|
||
|
|
public int getRow() {
|
||
|
|
return ivRow;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The field length.
|
||
|
|
*/
|
||
|
|
public int getLength() {
|
||
|
|
return ivLength;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Called every time the field contents changes.
|
||
|
|
* It fires the XI5250FieldEvent.VALUE_CHANGED event.
|
||
|
|
*/
|
||
|
|
protected void setMDTOn() {
|
||
|
|
ivFFW[0] |= 0x08;
|
||
|
|
processFieldEvent(new XI5250FieldEvent(XI5250FieldEvent.VALUE_CHANGED, this));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public void resetMDT() {
|
||
|
|
ivFFW[0] &= ~0x08;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* True if it was created as bypass field
|
||
|
|
*/
|
||
|
|
public boolean isOrgBypassField() {
|
||
|
|
return ((ivFFW[0] & 0x20) != 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* True if it was created or it became a bypass field
|
||
|
|
* return (isOrgBypassField() || (!isEnabled());
|
||
|
|
* @see #isEnabled()
|
||
|
|
*/
|
||
|
|
public boolean isBypassField() {
|
||
|
|
return (isOrgBypassField() || !isEnabled());
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isDupEnabled() {
|
||
|
|
return ((ivFFW[0] & 0x10) != 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isMDTOn() {
|
||
|
|
return ((ivFFW[0] & 0x08) != 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isAlphabeticShift() {
|
||
|
|
return ((ivFFW[0] & 0x07) == 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isAlphabeticOnly() {
|
||
|
|
return ((ivFFW[0] & 0x07) == 0x01);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isNumericShift() {
|
||
|
|
return ((ivFFW[0] & 0x07) == 0x02);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isNumericOnly() {
|
||
|
|
return ((ivFFW[0] & 0x07) == 0x03);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isDigitsOnly() {
|
||
|
|
return ((ivFFW[0] & 0x07) == 0x05);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.<br>
|
||
|
|
* Magnetic stripe reader, selector light pen, ...
|
||
|
|
*/
|
||
|
|
public boolean isIOOnly() {
|
||
|
|
return ((ivFFW[0] & 0x07) == 0x06);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isSignedNumeric() {
|
||
|
|
return ((ivFFW[0] & 0x07) == 0x07);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isAutoEnter() {
|
||
|
|
return ((ivFFW[1] & 0x80) != 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isExitRequired() {
|
||
|
|
return ((ivFFW[1] & 0x40) != 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isMonocase() {
|
||
|
|
return ((ivFFW[1] & 0x20) != 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isMandatoryEnter() {
|
||
|
|
return ((ivFFW[1] & 0x08) != 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isRightAdjustZeroFill() {
|
||
|
|
return ((ivFFW[1] & 0x07) == 0x05);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isRightAdjustBlankFill() {
|
||
|
|
return ((ivFFW[1] & 0x07) == 0x06);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Used to query Field Format Word flags.
|
||
|
|
*/
|
||
|
|
public boolean isMandatoryFill() {
|
||
|
|
return ((ivFFW[1] & 0x07) == 0x07);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Key used to order fields in XI5250FieldsList.
|
||
|
|
* Simply returns the field linear position in the 5250 buffer.
|
||
|
|
*/
|
||
|
|
protected int getSortKey() {
|
||
|
|
return ivCrt.toLinearPos(ivCol, ivRow);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private void updateStr() {
|
||
|
|
ivStr = ivCrt.getString(ivCol, ivRow, ivInputLen);
|
||
|
|
//!!V se lunghezza stringa = 0 generare eccezione
|
||
|
|
ivFldPos = ivCrt.toLinearPos(ivCol, ivRow);
|
||
|
|
ivCurPos = ivCrt.toLinearPos(ivCrt.getCursorCol(), ivCrt.getCursorRow());
|
||
|
|
ivPos = ivCurPos - ivFldPos;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected void processKeyEvent(KeyEvent e) {
|
||
|
|
//!!1.04c
|
||
|
|
processFieldEvent(new XI5250FieldEvent(XI5250FieldEvent.KEY_EVENT,
|
||
|
|
this, e));
|
||
|
|
|
||
|
|
if (e.isConsumed())
|
||
|
|
return;
|
||
|
|
|
||
|
|
switch (e.getID()) {
|
||
|
|
//
|
||
|
|
case KeyEvent.KEY_TYPED:
|
||
|
|
if (XI5250Crt.isCharKey(e)) {
|
||
|
|
if (processKeyChar(e.getKeyChar()))
|
||
|
|
e.consume();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case KeyEvent.KEY_PRESSED:
|
||
|
|
if (processOtherKey(e))
|
||
|
|
e.consume();
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case KeyEvent.KEY_RELEASED:
|
||
|
|
ivCrt.ivDropKeyChar = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected int insertChar(char aCh, int col, int row,
|
||
|
|
boolean insert, boolean fromKeyboard) {//!!1.04
|
||
|
|
if (isIOOnly() && fromKeyboard) {
|
||
|
|
return 4; // Do not accept keyboard input
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((isDigitsOnly() && !(aCh >= '0' && aCh <= '9'))) {
|
||
|
|
// 10 = only chars between 0 and 9
|
||
|
|
return 10;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((isSignedNumeric() && !(aCh >= '0' && aCh <= '9')) ||
|
||
|
|
(isNumericOnly() && !((aCh >= '0' && aCh <= '9') ||
|
||
|
|
aCh == ' ' || aCh == '+' || aCh == '-' ||
|
||
|
|
aCh == '.' || aCh == ','))
|
||
|
|
) {
|
||
|
|
// 9 = numeric field
|
||
|
|
return 9;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isMonocase())
|
||
|
|
aCh = Character.toUpperCase(aCh);
|
||
|
|
|
||
|
|
updateStr();
|
||
|
|
|
||
|
|
ivCurPos = ivCrt.toLinearPos(col, row);
|
||
|
|
ivPos = ivCurPos - ivFldPos;
|
||
|
|
|
||
|
|
if (ivPos < 0 || ivPos >= ivLength)
|
||
|
|
throw new IllegalStateException("");
|
||
|
|
|
||
|
|
StringBuilder strBuf = new StringBuilder(ivStr);
|
||
|
|
|
||
|
|
if (!insert) {
|
||
|
|
strBuf.setCharAt(ivPos, aCh);
|
||
|
|
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos, ivPos + 1),
|
||
|
|
col, row, ivAttr);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (strBuf.charAt(ivInputLen - 1) != '\u0000' &&
|
||
|
|
strBuf.charAt(ivInputLen - 1) != ' ') {
|
||
|
|
// 12 = field is full
|
||
|
|
return 12;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
strBuf.insert(ivPos, aCh);
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos, ivInputLen),
|
||
|
|
col, row, ivAttr);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
setMDTOn(); // field modified
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected boolean processKeyChar(char aCh) {
|
||
|
|
if (ivCrt.ivDropKeyChar) {
|
||
|
|
ivCrt.ivDropKeyChar = false;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
int error = insertChar(aCh, ivCrt.getCursorCol(), ivCrt.getCursorRow(),
|
||
|
|
ivCrt.isInsertState(), true);
|
||
|
|
if (error > 0) {
|
||
|
|
ivCrt.userError(error);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// is cursor on last char ??
|
||
|
|
if (ivPos < (ivInputLen - 1))
|
||
|
|
ivCrt.moveCursor(1, 0);
|
||
|
|
else {
|
||
|
|
// send auto enter (-1 as modifier) see XI5250Emulator.processKeyEnter()
|
||
|
|
if (isAutoEnter())
|
||
|
|
ivCrt.doProcessKeyEvent(new KeyEvent(ivCrt, KeyEvent.KEY_PRESSED, 0,
|
||
|
|
-1, KeyEvent.VK_ENTER, (char)KeyEvent.VK_ENTER));
|
||
|
|
// send auto tab
|
||
|
|
else if (!isExitRequired())
|
||
|
|
ivCrt.doProcessKeyEvent(new KeyEvent(ivCrt, KeyEvent.KEY_PRESSED, 0, 0,
|
||
|
|
KeyEvent.VK_TAB, (char)KeyEvent.VK_TAB));
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
/*!!1.04
|
||
|
|
protected boolean processKeyChar(char aCh) {
|
||
|
|
if (ivCrt.ivDropKeyChar) {
|
||
|
|
ivCrt.ivDropKeyChar = false;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((isDigitsOnly() && !(aCh >= '0' && aCh <= '9'))) {
|
||
|
|
// 10 = only chars between 0 and 9
|
||
|
|
ivCrt.userError(10);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((isSignedNumeric() && !(aCh >= '0' && aCh <= '9')) ||
|
||
|
|
(isNumericOnly() && !((aCh >= '0' && aCh <= '9') ||
|
||
|
|
aCh == ' ' || aCh == '+' || aCh == '-' ||
|
||
|
|
aCh == '.' || aCh == ','))
|
||
|
|
) {
|
||
|
|
// 9 = numeric field
|
||
|
|
ivCrt.userError(9);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isMonocase())
|
||
|
|
aCh = Character.toUpperCase(aCh);
|
||
|
|
|
||
|
|
updateStr();
|
||
|
|
StringBuilder strBuf = new StringBuilder(ivStr);
|
||
|
|
|
||
|
|
if (!ivCrt.isInsertState()) {
|
||
|
|
strBuf.setCharAt(ivPos, aCh);
|
||
|
|
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos, ivPos + 1),
|
||
|
|
ivCrt.getCursorCol(), ivCrt.getCursorRow(), ivAttr);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (strBuf.charAt(ivInputLen - 1) != '\u0000' &&
|
||
|
|
strBuf.charAt(ivInputLen - 1) != ' ') {
|
||
|
|
// 12 = field is full
|
||
|
|
ivCrt.userError(12);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
strBuf.insert(ivPos, aCh);
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos, ivInputLen),
|
||
|
|
ivCrt.getCursorCol(), ivCrt.getCursorRow(), ivAttr);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
setMDTOn(); // field modified
|
||
|
|
|
||
|
|
// is cursor on last char ??
|
||
|
|
if (ivPos < (ivInputLen - 1))
|
||
|
|
ivCrt.moveCursor(1, 0);
|
||
|
|
else {
|
||
|
|
// send auto enter (-1 as modifier)
|
||
|
|
if (isAutoEnter())
|
||
|
|
ivCrt.doProcessKeyEvent(new KeyEvent(ivCrt, KeyEvent.KEY_PRESSED, 0,
|
||
|
|
-1, KeyEvent.VK_ENTER));
|
||
|
|
// send auto tab
|
||
|
|
else if (!isExitRequired())
|
||
|
|
ivCrt.doProcessKeyEvent(new KeyEvent(ivCrt, KeyEvent.KEY_PRESSED, 0, 0,
|
||
|
|
KeyEvent.VK_TAB));
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected boolean processOtherKey(KeyEvent e) {
|
||
|
|
switch (e.getKeyCode()) {
|
||
|
|
case KeyEvent.VK_BACK_SPACE:
|
||
|
|
return processBackSpace(e.getModifiers());
|
||
|
|
//
|
||
|
|
case KeyEvent.VK_DELETE:
|
||
|
|
return processDelete(e.getModifiers());
|
||
|
|
//
|
||
|
|
case KeyEvent.VK_ADD:
|
||
|
|
ivCrt.ivDropKeyChar = true;
|
||
|
|
doFieldExit(false);
|
||
|
|
return true;
|
||
|
|
//
|
||
|
|
case KeyEvent.VK_SUBTRACT:
|
||
|
|
ivCrt.ivDropKeyChar = true;
|
||
|
|
if (isNumericOnly() || isSignedNumeric()) {
|
||
|
|
doFieldExit(true);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
// 16 = field- not valid
|
||
|
|
ivCrt.userError(16);
|
||
|
|
return true;
|
||
|
|
//
|
||
|
|
case KeyEvent.VK_ENTER:
|
||
|
|
return processEnter(e.getModifiers());
|
||
|
|
//
|
||
|
|
case KeyEvent.VK_END:
|
||
|
|
return processEnd(e.getModifiers());
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected boolean processBackSpace(int aModifier) {
|
||
|
|
switch (aModifier) {
|
||
|
|
case 0:
|
||
|
|
updateStr();
|
||
|
|
if (ivPos == 0) {
|
||
|
|
ivCrt.doProcessKeyEvent(new KeyEvent(ivCrt, KeyEvent.KEY_PRESSED, 0, KeyEvent.SHIFT_MASK,
|
||
|
|
KeyEvent.VK_TAB, (char)KeyEvent.VK_TAB));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ivCrt.moveCursor(-1, 0);
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
case KeyEvent.SHIFT_MASK:
|
||
|
|
updateStr();
|
||
|
|
if (ivPos == 0) {
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ivCrt.moveCursor(-1, 0);
|
||
|
|
updateStr();
|
||
|
|
StringBuilder strBuf = new StringBuilder(ivStr);
|
||
|
|
for (int i = ivPos + 1; i < ivStr.length(); i++)
|
||
|
|
strBuf.setCharAt(i - 1, strBuf.charAt(i));
|
||
|
|
strBuf.setCharAt(ivStr.length() - 1, '\u0000');
|
||
|
|
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos),
|
||
|
|
ivCrt.getCursorCol(), ivCrt.getCursorRow(), ivAttr);
|
||
|
|
|
||
|
|
setMDTOn(); // field modified
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected boolean processDelete(int aModifier) {
|
||
|
|
switch (aModifier) {
|
||
|
|
case 0:
|
||
|
|
updateStr();
|
||
|
|
StringBuilder strBuf = new StringBuilder(ivStr);
|
||
|
|
for (int i = ivPos + 1; i < ivStr.length(); i++)
|
||
|
|
strBuf.setCharAt(i - 1, strBuf.charAt(i));
|
||
|
|
strBuf.setCharAt(ivStr.length() - 1, '\u0000');
|
||
|
|
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos),
|
||
|
|
ivCrt.getCursorCol(), ivCrt.getCursorRow(), ivAttr);
|
||
|
|
|
||
|
|
setMDTOn(); // field modified
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected boolean processEnter(int aModifier) {
|
||
|
|
switch (aModifier) {
|
||
|
|
case KeyEvent.SHIFT_MASK:
|
||
|
|
doFieldExit(false);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
private void doFieldExit(boolean isMinus) {
|
||
|
|
XIEbcdicTranslator translator = getCrt().getTranslator();
|
||
|
|
|
||
|
|
updateStr();
|
||
|
|
StringBuilder strBuf = new StringBuilder(ivStr);
|
||
|
|
|
||
|
|
for (int i = ivPos; i < ivStr.length(); i++)
|
||
|
|
strBuf.setCharAt(i, '\u0000');
|
||
|
|
|
||
|
|
for ( ; ivPos > 0 && strBuf.charAt(ivPos - 1) == '\u0000'; ivPos--)
|
||
|
|
;
|
||
|
|
|
||
|
|
// see IBM 5250 function reference manual page 2-70
|
||
|
|
if (isNumericOnly()) {
|
||
|
|
if (isMinus && ivPos > 0) {
|
||
|
|
char ch = strBuf.charAt(ivPos - 1);
|
||
|
|
if (ch != '+' && ch != '-' && ch != '.' && ch != ',' && ch != ' ') {
|
||
|
|
byte xx = translator.toEBCDIC(strBuf.charAt(ivPos - 1));
|
||
|
|
xx &= 0x0F;
|
||
|
|
xx |= 0xD0;
|
||
|
|
strBuf.setCharAt(ivPos - 1, translator.toChar(xx));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ivCrt.userError(26);
|
||
|
|
return ;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isRightAdjustZeroFill() || isRightAdjustBlankFill() ||
|
||
|
|
isSignedNumeric()) {
|
||
|
|
int i;
|
||
|
|
|
||
|
|
// right allign
|
||
|
|
for (i = 0; i < ivPos; i++)
|
||
|
|
strBuf.setCharAt(ivStr.length() - i - 1, strBuf.charAt(ivPos - i - 1));
|
||
|
|
|
||
|
|
for (i = ivStr.length() - ivPos - 1; i >= 0; i--)
|
||
|
|
strBuf.setCharAt(i, (isRightAdjustZeroFill()) ? '0' : ' ');
|
||
|
|
|
||
|
|
String str = new String(strBuf);
|
||
|
|
|
||
|
|
// see IBM 5250 function reference manual page 2-70
|
||
|
|
if (isSignedNumeric())
|
||
|
|
str += (isMinus) ? '-' : '\u0000';
|
||
|
|
|
||
|
|
ivCrt.drawString(str, ivCol, ivRow, ivAttr);
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos),
|
||
|
|
ivCrt.getCursorCol(), ivCrt.getCursorRow(), ivAttr);
|
||
|
|
}
|
||
|
|
|
||
|
|
setMDTOn(); // field modified
|
||
|
|
|
||
|
|
// send tab
|
||
|
|
ivCrt.doProcessKeyEvent(new KeyEvent(ivCrt, KeyEvent.KEY_PRESSED, 0, 0,
|
||
|
|
KeyEvent.VK_TAB, (char)KeyEvent.VK_TAB));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
protected boolean processEnd(int aModifier) {
|
||
|
|
switch (aModifier) {
|
||
|
|
case 0:
|
||
|
|
int i;
|
||
|
|
updateStr();
|
||
|
|
for (i = ivStr.length() - 1; (i >= 0) && (ivStr.charAt(i) <= ' '); i--)
|
||
|
|
;
|
||
|
|
int xx = ivCrt.toLinearPos(ivCol, ivRow) + Math.min(i + 1, ivInputLen - 1);
|
||
|
|
ivCrt.setCursorPos(ivCrt.toColPos(xx), ivCrt.toRowPos(xx));
|
||
|
|
return true;
|
||
|
|
case KeyEvent.SHIFT_MASK:
|
||
|
|
updateStr();
|
||
|
|
StringBuilder strBuf = new StringBuilder(ivStr);
|
||
|
|
for (int j = ivPos; j < ivStr.length(); j++)
|
||
|
|
strBuf.setCharAt(j, '\u0000');
|
||
|
|
|
||
|
|
ivCrt.drawString(new String(strBuf).substring(ivPos),
|
||
|
|
ivCrt.getCursorCol(), ivCrt.getCursorRow(), ivAttr);
|
||
|
|
|
||
|
|
setMDTOn(); // field modified
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the number of rows occupied by this field
|
||
|
|
* NOTE: a field can be wrapped on more than one line
|
||
|
|
*/
|
||
|
|
public int getNRows() {
|
||
|
|
return ((ivCol + ivLength - 1) / ivCrt.getCrtSize().width + 1); //!!1.03c
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the bounding rectangle (in pixel).
|
||
|
|
*/
|
||
|
|
public Rectangle getBoundingRect() {
|
||
|
|
Dimension charSize = ivCrt.getCharSize();
|
||
|
|
int rows = getNRows();
|
||
|
|
|
||
|
|
if (rows <= 1)
|
||
|
|
return new Rectangle(ivCol * charSize.width,
|
||
|
|
ivRow * charSize.height,
|
||
|
|
ivLength * charSize.width,
|
||
|
|
rows * charSize.height);
|
||
|
|
else
|
||
|
|
return new Rectangle(0 * charSize.width,
|
||
|
|
ivRow * charSize.height,
|
||
|
|
//!!1.04c ivCrt.getSize().width,
|
||
|
|
ivCrt.getCrtBufferSize().width,
|
||
|
|
rows * charSize.height);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns all the rows occupied by the fields.
|
||
|
|
* NOTE: coordinates are expressed in chars.
|
||
|
|
*/
|
||
|
|
public Rectangle[] getRows() {
|
||
|
|
int rows = getNRows();
|
||
|
|
//Dimension charSize = ivCrt.getCharSize();
|
||
|
|
Rectangle[] rcts = new Rectangle[rows];
|
||
|
|
|
||
|
|
// split line to handle wrap
|
||
|
|
int len = ivLength;
|
||
|
|
int x = ivCol;
|
||
|
|
int y = ivRow;
|
||
|
|
int dx;
|
||
|
|
int i = 0;
|
||
|
|
|
||
|
|
while (len > 0) {
|
||
|
|
dx = Math.min(ivCrt.getCrtSize().width - x, len);
|
||
|
|
|
||
|
|
rcts[i++] = new Rectangle(x, y, dx, 1);
|
||
|
|
|
||
|
|
len -= dx;
|
||
|
|
x = 0;
|
||
|
|
++y;
|
||
|
|
}
|
||
|
|
|
||
|
|
return rcts;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns all the rectangles that the field is composed of.
|
||
|
|
* NOTE: coordinates are expressed in pixel and are relative to XI5250Crt panel.
|
||
|
|
*/
|
||
|
|
public Rectangle[] getRowsRects() {
|
||
|
|
Rectangle[] rcts = getRows();
|
||
|
|
|
||
|
|
for (int i = 0; i < rcts.length; i++)
|
||
|
|
rcts[i] = ivCrt.toPoints(rcts[i].x, rcts[i].y, rcts[i].width, rcts[i].height);
|
||
|
|
|
||
|
|
return rcts;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Repaint the field.
|
||
|
|
*/
|
||
|
|
public void repaint() {
|
||
|
|
Rectangle rt = getBoundingRect();
|
||
|
|
ivCrt.repaint(rt.x, rt.y, rt.width, rt.height);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Coordinates are relative to the field bounding rectangle
|
||
|
|
*/
|
||
|
|
protected void paint(Graphics g) {
|
||
|
|
processFieldPaintEvent(
|
||
|
|
new XI5250FieldPaintEvent(XI5250FieldPaintEvent.ROW_PAINT,
|
||
|
|
this, g));
|
||
|
|
|
||
|
|
Rectangle clip = g.getClipBounds();
|
||
|
|
if (clip == null)
|
||
|
|
return;
|
||
|
|
|
||
|
|
Rectangle[] rowsRects = getRowsRects();
|
||
|
|
|
||
|
|
// request a paint for each row
|
||
|
|
for (int j = 0; j < rowsRects.length; j++) {
|
||
|
|
Rectangle fr = new Rectangle(rowsRects[j]);
|
||
|
|
// coord relative to field bounding rect position
|
||
|
|
fr.translate(-getBoundingRect().x, -getBoundingRect().y);
|
||
|
|
|
||
|
|
if (clip.intersects(fr)) {
|
||
|
|
Graphics fg = g.create();
|
||
|
|
// set new clipping rectangle, but do not translate origin
|
||
|
|
fg.clipRect(fr.x, fr.y, fr.width, fr.height);
|
||
|
|
try {
|
||
|
|
rowPaint(fg);
|
||
|
|
}
|
||
|
|
finally {
|
||
|
|
fg.dispose();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isOrgBypassField())
|
||
|
|
drawBorder(g);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Draws the field borders (a field can be splitted on more than one crt
|
||
|
|
* line).
|
||
|
|
*/
|
||
|
|
protected void drawBorder(Graphics g) {
|
||
|
|
int borderStyle = getUsedBorderStyle();
|
||
|
|
if (borderStyle <= NO_BORDER)
|
||
|
|
return;
|
||
|
|
|
||
|
|
Rectangle[] rowsRects = getRowsRects();
|
||
|
|
|
||
|
|
for (int i = 0; i < rowsRects.length; i++)
|
||
|
|
rowsRects[i].translate(-getBoundingRect().x, -getBoundingRect().y);
|
||
|
|
|
||
|
|
Color bg = getCrt().getDefBackground();
|
||
|
|
Color cl1, cl2;
|
||
|
|
if (isCurrentField()) {
|
||
|
|
cl1 = (borderStyle == RAISED_BORDER) ? bg.darker().darker().darker() :
|
||
|
|
bg.darker();
|
||
|
|
cl2 = (borderStyle == RAISED_BORDER) ? bg.darker() :
|
||
|
|
bg.darker().darker().darker();
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
cl1 = (borderStyle == RAISED_BORDER) ? bg.darker() :
|
||
|
|
bg;
|
||
|
|
cl2 = (borderStyle == RAISED_BORDER) ? bg :
|
||
|
|
bg.darker();
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (rowsRects.length) {
|
||
|
|
//
|
||
|
|
case 0:
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case 1:
|
||
|
|
g.setColor(cl1);
|
||
|
|
g.drawLine(rowsRects[0].x,
|
||
|
|
rowsRects[0].y,
|
||
|
|
rowsRects[0].x,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1);
|
||
|
|
g.drawLine(rowsRects[0].x,
|
||
|
|
rowsRects[0].y,
|
||
|
|
rowsRects[0].x + rowsRects[0].width - 1,
|
||
|
|
rowsRects[0].y);
|
||
|
|
|
||
|
|
g.setColor(cl2);
|
||
|
|
g.drawLine(rowsRects[0].x + rowsRects[0].width - 1,
|
||
|
|
rowsRects[0].y,
|
||
|
|
rowsRects[0].x + rowsRects[0].width - 1,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1);
|
||
|
|
g.drawLine(rowsRects[0].x,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1,
|
||
|
|
rowsRects[0].x + rowsRects[0].width - 1,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1);
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
case 2:
|
||
|
|
int dx = Math.max(0, (rowsRects[1].x + rowsRects[1].width - 1) - rowsRects[0].x);
|
||
|
|
|
||
|
|
g.setColor(cl1);
|
||
|
|
g.drawLine(rowsRects[0].x,
|
||
|
|
rowsRects[0].y,
|
||
|
|
rowsRects[0].x,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1);
|
||
|
|
g.drawLine(rowsRects[0].x,
|
||
|
|
rowsRects[0].y,
|
||
|
|
rowsRects[0].x + rowsRects[0].width - 1,
|
||
|
|
rowsRects[0].y);
|
||
|
|
|
||
|
|
g.drawLine(rowsRects[1].x,
|
||
|
|
rowsRects[1].y,
|
||
|
|
rowsRects[1].x + rowsRects[1].width - 1 - dx,
|
||
|
|
rowsRects[1].y);
|
||
|
|
|
||
|
|
g.setColor(cl2);
|
||
|
|
g.drawLine(rowsRects[1].x + rowsRects[1].width - 1,
|
||
|
|
rowsRects[1].y,
|
||
|
|
rowsRects[1].x + rowsRects[1].width - 1,
|
||
|
|
rowsRects[1].y + rowsRects[1].height - 1);
|
||
|
|
g.drawLine(rowsRects[1].x,
|
||
|
|
rowsRects[1].y + rowsRects[1].height - 1,
|
||
|
|
rowsRects[1].x + rowsRects[1].width - 1,
|
||
|
|
rowsRects[1].y + rowsRects[1].height - 1);
|
||
|
|
|
||
|
|
g.drawLine(rowsRects[0].x + dx,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1,
|
||
|
|
rowsRects[0].x + rowsRects[0].width - 1,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1);
|
||
|
|
break;
|
||
|
|
//
|
||
|
|
default:
|
||
|
|
int l = rowsRects.length - 1;
|
||
|
|
|
||
|
|
g.setColor(cl1);
|
||
|
|
g.drawLine(rowsRects[0].x,
|
||
|
|
rowsRects[0].y,
|
||
|
|
rowsRects[0].x,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1);
|
||
|
|
g.drawLine(rowsRects[0].x,
|
||
|
|
rowsRects[0].y,
|
||
|
|
rowsRects[0].x + rowsRects[0].width - 1,
|
||
|
|
rowsRects[0].y);
|
||
|
|
|
||
|
|
g.drawLine(rowsRects[1].x,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1,
|
||
|
|
rowsRects[0].x,
|
||
|
|
rowsRects[0].y + rowsRects[0].height - 1);
|
||
|
|
|
||
|
|
g.setColor(cl2);
|
||
|
|
g.drawLine(rowsRects[l].x + rowsRects[l].width - 1,
|
||
|
|
rowsRects[l].y,
|
||
|
|
rowsRects[l].x + rowsRects[l].width - 1,
|
||
|
|
rowsRects[l].y + rowsRects[l].height - 1);
|
||
|
|
g.drawLine(rowsRects[l].x,
|
||
|
|
rowsRects[l].y + rowsRects[l].height - 1,
|
||
|
|
rowsRects[l].x + rowsRects[l].width - 1,
|
||
|
|
rowsRects[l].y + rowsRects[l].height - 1);
|
||
|
|
|
||
|
|
g.drawLine(rowsRects[l].x + rowsRects[l].width - 1,
|
||
|
|
rowsRects[l - 1].y + rowsRects[l - 1].height - 1,
|
||
|
|
rowsRects[l - 1].x + rowsRects[l - 1].width - 1,
|
||
|
|
rowsRects[l - 1].y + rowsRects[l - 1].height - 1);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Called for each rectangle returned by getRowsRects.
|
||
|
|
* Coordinates are relative to the field bounding rectangle.
|
||
|
|
* @see #getRowsRects
|
||
|
|
*/
|
||
|
|
protected void rowPaint(Graphics g) {
|
||
|
|
processFieldPaintEvent(new XI5250FieldPaintEvent(XI5250FieldPaintEvent.ROW_PAINT,
|
||
|
|
this, g));
|
||
|
|
if (!ivEnabled) {
|
||
|
|
Rectangle rt = getBoundingRect();
|
||
|
|
g.setColor(Color.white);
|
||
|
|
|
||
|
|
int hh = rt.height;
|
||
|
|
for (int x = -hh; x < rt.width; x += 8)
|
||
|
|
g.drawLine(x, hh, x + hh, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Field has changed its dimensions.
|
||
|
|
*/
|
||
|
|
protected void resized() {
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Field has changed its activated (focus) state.
|
||
|
|
*/
|
||
|
|
protected void activated(boolean activated) {
|
||
|
|
repaint(); //!!1.15
|
||
|
|
processFieldEvent(new XI5250FieldEvent((activated) ? XI5250FieldEvent.ACTIVATED :
|
||
|
|
XI5250FieldEvent.DEACTIVATED,
|
||
|
|
this));
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public final boolean isCurrentField() {
|
||
|
|
return ivCrt.getCurrentField() == this;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Enable or disable the field.
|
||
|
|
*/
|
||
|
|
public void setEnabled(boolean flag) {
|
||
|
|
if (flag == ivEnabled)
|
||
|
|
return;
|
||
|
|
ivEnabled = flag;
|
||
|
|
repaint();
|
||
|
|
processFieldEvent(
|
||
|
|
new XI5250FieldEvent(XI5250FieldEvent.ENABLED_STATE_CHANGED, this));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public boolean isEnabled() {
|
||
|
|
return ivEnabled;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Changes the field border style.
|
||
|
|
*/
|
||
|
|
public void setBorderStyle(int aStyle) {
|
||
|
|
if (aStyle == ivBorderStyle)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (aStyle < DEFAULT_BORDER || aStyle > LOWERED_BORDER)
|
||
|
|
throw new IllegalArgumentException("Wrong border style argument");
|
||
|
|
|
||
|
|
ivBorderStyle = aStyle;
|
||
|
|
repaint();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @see #getUsedBorderStyle
|
||
|
|
*/
|
||
|
|
public int getBorderStyle() {
|
||
|
|
return ivBorderStyle;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the real used border style.
|
||
|
|
* It takes care of the default border style defined with
|
||
|
|
* XI5250Crt.setDefFieldsBorderStyle
|
||
|
|
* @see XI5250Crt#setDefFieldsBorderStyle
|
||
|
|
*/
|
||
|
|
public int getUsedBorderStyle() {
|
||
|
|
int style = getBorderStyle();
|
||
|
|
return (style != DEFAULT_BORDER) ? style : ivCrt.getDefFieldsBorderStyle();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
@Override
|
||
|
|
public String toString() {
|
||
|
|
return super.toString() + " [FFW=[" + XITelnet.toHex(ivFFW[0]) + "," +
|
||
|
|
XITelnet.toHex(ivFFW[1]) + "]," +
|
||
|
|
"FCW=[" + XITelnet.toHex(ivFCW[0]) + "," +
|
||
|
|
XITelnet.toHex(ivFCW[1]) + "]," +
|
||
|
|
"Attr=" + XITelnet.toHex((byte)ivAttr) + "," +
|
||
|
|
"(" + ivCol + "," + ivRow + ")" +
|
||
|
|
"Len=" + ivLength + "]";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Multicast Listener for XI5250Field
|
||
|
|
* @version
|
||
|
|
* @author Valentino Proietti - Infordata S.p.A.
|
||
|
|
*/
|
||
|
|
private static class Multicaster extends AWTEventMulticaster
|
||
|
|
implements XI5250FieldListener,
|
||
|
|
XI5250FieldPaintListener {
|
||
|
|
|
||
|
|
|
||
|
|
protected Multicaster(EventListener a, EventListener b) {
|
||
|
|
super(a, b);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//!!1.03a
|
||
|
|
@Override
|
||
|
|
protected EventListener remove(EventListener oldl) {
|
||
|
|
if (oldl == a) return b;
|
||
|
|
if (oldl == b) return a;
|
||
|
|
EventListener a2 = removeInternal(a, oldl);
|
||
|
|
EventListener b2 = removeInternal(b, oldl);
|
||
|
|
if (a2 == a && b2 == b)
|
||
|
|
return this;
|
||
|
|
return add(a2, b2);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static EventListener add(EventListener a, EventListener b) {
|
||
|
|
if (a == null) return b;
|
||
|
|
if (b == null) return a;
|
||
|
|
return new Multicaster(a, b);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static EventListener remove(EventListener a, EventListener b) {
|
||
|
|
return removeInternal(a, b);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public void activated(XI5250FieldEvent e) {
|
||
|
|
((XI5250FieldListener)a).activated(e);
|
||
|
|
((XI5250FieldListener)b).activated(e);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public void deactivated(XI5250FieldEvent e) {
|
||
|
|
((XI5250FieldListener)a).deactivated(e);
|
||
|
|
((XI5250FieldListener)b).deactivated(e);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public void valueChanged(XI5250FieldEvent e) {
|
||
|
|
((XI5250FieldListener)a).valueChanged(e);
|
||
|
|
((XI5250FieldListener)b).valueChanged(e);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public void enabledStateChanged(XI5250FieldEvent e) {
|
||
|
|
((XI5250FieldListener)a).enabledStateChanged(e);
|
||
|
|
((XI5250FieldListener)b).enabledStateChanged(e);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public void keyEvent(XI5250FieldEvent e) {
|
||
|
|
((XI5250FieldListener)a).keyEvent(e);
|
||
|
|
((XI5250FieldListener)b).keyEvent(e);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
public void fieldPaint(XI5250FieldPaintEvent e) {
|
||
|
|
((XI5250FieldPaintListener)a).fieldPaint(e);
|
||
|
|
((XI5250FieldPaintListener)b).fieldPaint(e);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public void rowPaint(XI5250FieldPaintEvent e) {
|
||
|
|
((XI5250FieldPaintListener)a).rowPaint(e);
|
||
|
|
((XI5250FieldPaintListener)b).rowPaint(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|