Hello I'm currently looking for a way to display a button with icon and label.
I want the icon to be on the left side and the label left-aligned on the right side of the Icon.
I don't think this is possible in openedge but maybe one has an idea for this.
I'm using an abl-frame and the button needs to be generated dynamically
I have a very ugly solution for you:
Create an image containing the entire face of the button. Icon and text included. Perhaps not a beautiful solution but you won't need to use .Net.
Basically it will just add the IMAGE-UP attribute for the button.
DEFINE BUTTON BUTTON-3
IMAGE-UP FILE "c:/temp/button.png":U
LABEL "Button 3"
SIZE 48 BY 4.29.
button.png:
Add that image to your button.
Result:
If you need to set different pictures based on contrast you will need to check Registry for contrast setting. That can be done something like this:
DEFINE VARIABLE cContrast AS CHARACTER NO-UNDO.
LOAD "Control Panel" BASE-KEY "HKEY_CURRENT_USER".
USE "Control Panel".
GET-KEY-VALUE SECTION "Accessibility\HighContrast" KEY "Flags" VALUE cContrast.
UNLOAD "Control Panel".
IF cContrast = "126" THEN
MESSAGE "Low contrast" VIEW-AS ALERT-BOX.
ELSE IF cContrast = "127" THEN
MESSAGE "High contrast" VIEW-AS ALERT-BOX.
If you are not on a completely obsolete version of Progress OpenEdge then you can use .Net controls, the visual designer in Progress Developer Studio for OpenEdge (PDSOE) will let you drag and drop the following together:
This generates the following source code (which you can also use to generate form creation):
USING Progress.Lang.*.
USING Progress.Windows.Form.
BLOCK-LEVEL ON ERROR UNDO, THROW.
CLASS button INHERITS Form:
DEFINE PRIVATE VARIABLE button1 AS System.Windows.Forms.Button NO-UNDO.
DEFINE PRIVATE VARIABLE components AS System.ComponentModel.IContainer NO-UNDO.
CONSTRUCTOR PUBLIC button ( ):
SUPER().
InitializeComponent().
THIS-OBJECT:ComponentsCollection:ADD(THIS-OBJECT:components).
CATCH e AS Progress.Lang.Error:
UNDO, THROW e.
END CATCH.
END CONSTRUCTOR.
METHOD PRIVATE VOID InitializeComponent( ):
/* NOTE: The following method is automatically generated.
We strongly suggest that the contents of this method only be modified using the
Visual Designer to avoid any incompatible modifications.
Modifying the contents of this method using a code editor will invalidate any support for this file. */
#VisualDesigner.FormMember (NeedsInitialize="true").
DEFINE VARIABLE resources AS Progress.Util.ResourceManager NO-UNDO.
resources = NEW Progress.Util.ResourceManager("button").
THIS-OBJECT:button1 = NEW System.Windows.Forms.Button().
THIS-OBJECT:SuspendLayout().
/* */
/* button1 */
/* */
THIS-OBJECT:button1:Image = CAST(resources:GetObject("button1.Image"), System.Drawing.Image).
THIS-OBJECT:button1:ImageAlign = System.Drawing.ContentAlignment:MiddleLeft.
THIS-OBJECT:button1:Location = NEW System.Drawing.Point(13, 212).
THIS-OBJECT:button1:Name = "button1".
THIS-OBJECT:button1:Size = NEW System.Drawing.Size(108, 42).
THIS-OBJECT:button1:TabIndex = 0.
THIS-OBJECT:button1:Text = "Exit".
THIS-OBJECT:button1:TextAlign = System.Drawing.ContentAlignment:MiddleRight.
THIS-OBJECT:button1:UseCompatibleTextRendering = TRUE.
THIS-OBJECT:button1:UseVisualStyleBackColor = TRUE.
/* */
/* button */
/* */
THIS-OBJECT:ClientSize = NEW System.Drawing.Size(292, 266).
THIS-OBJECT:Controls:Add(THIS-OBJECT:button1).
THIS-OBJECT:Name = "button".
THIS-OBJECT:Text = "button".
THIS-OBJECT:ResumeLayout(FALSE).
CATCH e AS Progress.Lang.Error:
UNDO, THROW e.
END CATCH.
END METHOD.
DESTRUCTOR PUBLIC button ( ):
END DESTRUCTOR.
END CLASS.
The drag and drop method will also by default create a resx file which is an xml file containing the resources used, the image is encoded in there:
<data mimetype="application/x-microsoft.net.object.bytearray.base64" name="button1.Image" type="System.Drawing.Bitmap, System.Drawing">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wgAADsIBFShKgAAAAJFJREFUOE/N0EEOgCAMRFEP4tL738wz1CaDQYa2FmThX5FIH8gmi/otdO4HFtNV
aNSikfproxZtbt4ob/Xb+LEzkHmeAcWW95Uh5O0OjslCIDxFsyHtORMTyIU0DGcULYK0pKK93AjK/I3o
Ip+gsrojuo+hYCC2Gig+E3lchTIKMq0Ceed49fvtx860DKIWQSIXxapUG1GIZgoAAAAASUVORK5CYII=
</value>
When generating your forms with code you do not need the resx files and can load images etc from the file system.
Related
so I am using JavFX to create a form that stores all the answers in a csv file. I need to create a dropdown menu that allows the users to select an option, which is then recorded in the csv file. I have tried a lot of different options, however I think comboBox is the best option.
I have no problem creating the ComboBox, I only run into problems when it comes to the method to get the value of the box.
Can someone help me find a solution, or suggest what another JavaFX menu I can use?
This is the code I have right now:
public VBox setFamiliar(){
Button button = new Button();
button.setOnAction(e -> toString());
familiarComboBox = new ComboBox<>();
familiarVBox = new VBox();
familiarComboBox.getItems().addAll("Irmão", "Irmã", "Avó", "Avô", "Tio", "Tia", "Pai", "Mãe");
familiarVBox.getChildren().add(familiarComboBox);
familiarVBox.getChildren().add(button);
return familiarVBox;
}
Here I set the ComboBox, this part doesnt seem to have a problem because it appears and I can select an item. I created a separate void toString() method that sets the value of a variable to the current selected item
public void toString(ActionEvent e){
familiar = familiarComboBox.getSelectionModel().getSelectedItem().toString();
}
The problem is then in the get method to get the value that was selected.
public String getIrmao(){
if(familiar.equals("Irmão")){
return "2";
}
return "0";
I also tried to do familiarComboBox.getSelectionModel().getSelectedItem().equals(), and other variations of this combination.
If I understand your requirement -- that when a user makes a choice from the "Familiar" combo box, a value should be written immediately to a CSV file -- you don't need the getIrmao() method. You simply write the value out in the action which you are calling toString(...) (not a good choice of names), but which we will rename to handleFamiliarChange(...).
Now the method becomes
public void handleFamiliarChange(ActionEvent e){
final String familiar =
familiarComboBox.getSelectionModel().getSelectedItem().toString();
FileUtils.writeToCsvFile(familiar.equals("Irmão") ? 2 : 0);
}
where FileUtils.writeToCsvFile(...) is a method that does the file writing. Note that FileUtils is a class you have created to separate out file handling concerns -- your JavaFX view class should only concern itself with views.
I have a form with record. To create new one I have menuitem button which opens a new Form where you can create new record (and there is lots of logic which will not be easy to move into new record action on parent datasource). This menuitem has OpenMode = New so the new record is created in datasource.
When I am closing this new form I want to set caller to newly created record. I was trying to do it by.
TableName TableName;
FormDataSource FormDataSource;
boolean test;
#Task
element.args().caller().task(#taskF5);
FormDataSource = element.args().caller().dataSource('CallerDataSourceName');
FormDataSource.research();
TableName= getFirstSelection('ThisDatasourceName');
test = FormDataSource.findRecord(TableName);
The result of the findRecord is true and it looks like it is set the position for a second after second the position on grid switch to the 1. (And the result of the test is true.)
I move the seting position to the caller but it does not help. Is the problem in the menuitem open mode property? How can I ensure the position on the caller?
I am using AX2012
I end up with this solution. I am not setting position on the child but on the caller.
On a child I have this (+ hasMethod):
tableToFind = getFirstSelection(SQLTables_DS);
element.args().caller().setRecord(tableToFind);
it is in close under the super();
On the caller I have method:
public void setRecord(TableName _TableName)
{
boolean test;
CallerDataSourceName_DS.research();
test = CallerDataSourceName_DS.findRecord(_TableName);
CallerDataSourceName.refresh();
}
The same trick on the child in close does not work. I guess it is due to the OpenMode property.
I made a basic text editor that lets users insert predefined strings into the document with button clicks. What I need to do now is let the user define their own buttons and string values.
For example I have a button that inserts "Hello" into the text. The user may want to create a button that adds "Goodbye".
To accomplish this I figured I would create a .txt file called buttons.txt or something. i would readutfbytee, loop through it to create the buttons. problem is I know what I want to do but not sure where to start. Can someone give me a kick start?
Please check the following code as the simple way to externalize your button settings:
/*
buttons.txt content sample:
Helo=Hello World&Test=Test Inserted
*/
protected function loadSettings():void
{
var varLoader:URLLoader = new URLLoader();
varLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
varLoader.addEventListener(Event.COMPLETE, onSettingsLoaded);
varLoader.load(new URLRequest("data/buttons.txt"));
}
protected function onSettingsLoaded(event:Event):void
{
var varLoader:URLLoader = URLLoader(event.target);
var varButtons:URLVariables = varLoader.data;
var buttons:Dictionary = new Dictionary();
for(var label:String in varButtons{
buttons[label]=varButtons[label].toString().split(",");
}
//use parsed buttons dictionary
}
For starters you need to decide how you are going to store that data that the user enters.
A flex web app can't save any files to the server, so if you want to save this across multiple computers, you'll need a server to do the data saving / retrieval.
If you want to store the buttons just temporarily, and unique to one computer, you can stuff them into a SharedObject.
After you decide this, then you can get more specific on a question of how to do exactly what you're wanting.
I've created a simple ALV grid and populated the grid with data, now the grid is displayed after the selection screen. I'm not using custom container and display the grid in full screen.
Is there a property of ALV grid object that enables toolbar with buttons filter, sort, etc, that is normally on top of the grid?
So far this is what I have:
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = gr_alv
CHANGING
t_table = tbl_data
).
CATCH cx_salv_msg.
ENDTRY.
* initialize the alv settings - nothing done here for the moment.
PERFORM define_settings USING gr_alv.
* Display the ALV
gr_alv->display( ).
Each ALV function is implemented as a separate CLASS in Simple ALV, so you have to handle them separately. You do not need a custom control.
In order to add the toolbar:
data: lr_func TYPE REF TO CL_SALV_FUNCTIONS_LIST.
"Functions
lr_func = gr_alv->get_functions( ).
lr_func->set_all( ).
Complete ALV display:
form display_results.
data: ls_key type salv_s_layout_key,
lo_table type ref to cl_salv_table,
lo_cols type ref to cl_salv_columns_table,
lo_events type ref to cl_salv_events_table,
lo_funcs type ref to cl_salv_functions_list,
lo_layout type ref to cl_salv_layout,
lo_display type ref to cl_salv_display_settings,
lo_selections type ref to cl_salv_selections.
try.
call method cl_salv_table=>factory
exporting
list_display = abap_false
importing
r_salv_table = lo_table
changing
t_table = gt_list.
catch cx_salv_msg . "#EC NO_HANDLER
endtry.
"Events
create object go_events.
lo_events = lo_table->get_event( ).
set handler go_events->double_click for lo_events.
"Layouts
ls_key-report = sy-repid.
lo_layout = lo_table->get_layout( ).
lo_layout->set_key( ls_key ).
lo_layout->set_default( abap_true ).
lo_layout->set_save_restriction( ).
lo_layout->set_initial_layout( p_var ).
lo_cols = lo_table->get_columns( ).
perform change_columns changing lo_cols.
"Functions
lo_funcs = lo_table->get_functions( ).
lo_funcs->set_all( ).
"Display Settings
lo_display = lo_table->get_display_settings( ).
lo_display->set_striped_pattern( abap_true ).
"Selections
lo_selections = lo_table->get_selections( ).
lo_selections->set_selection_mode( if_salv_c_selection_mode=>row_column ).
lo_table->display( ).
endform. " DISPLAY_RESULTS
This is confusing at first when you use the ALV object model. If you use the ALV in fullscreen mode you have to reference a GUI status in your program, and use the method SET_SCREEN_STATUS on your grid instance. It's explained in the SAP Help here.
It helps to copy the GUI status SALV_TABLE_STANDARD from function group SALV_METADATA_STATUS into your report as a starting point, and then you can remove any functions you don't need. For example, if you copied the status into your program as ALV_STATUS, you would write:
gr_alv->set_screen_status( report = sy-repid
pfstatus = 'ALV_STATUS' ).
If you want to use the class-based model of setting up ALV functions, you have to embed the grid object in a custom container in a screen.
Seems what you need to do is get an instance of CL_SALV_FUNCTIONS_LIST from your grid object like so:
data: lr_func TYPE REF TO CL_SALV_FUNCTIONS_LIST.
lr_func = gr_alv->get_functions( ).
lr_func->set_all( ).
But, from there, it seems you need to do a bit or work. My advice: Look at the documentation on classes CL_SALV_TABLE and CL_SALV_FUNCTIONS_LIST (that is, click the documentation button when you display the class in transaction SE24). The latter tells you exactly what you need to do.
(Also, a little hint: Put your processing logic inside the try-catch block, because if the initialization fails, you might catch that exception but go on to try call a method on an uninstantiated or uninitialized class).
add a customer container to your gui
create an object of the class cl_gui_custom_container and supply the name of your container
create an instance of the class cl_gui_alv_grid and supply the custom container object
use the method set_table_for_first_display
this will display a toolbar with all buttons. you can control which buttons you want in the toolbar with the IT_TOOLBAR_EXCLUDING parameter to the set_table_for_first_display method.
I am working on the multifile uploader, and want to set the upload directory based on a selected questionID (which is the directory name) in my datagrid.
The code can be found here http://pastie.org/784185
Something like this:
I have set myQuestionID (the directory to upload to) so it is bindable (lines 136-137):
[Bindable] public var myQuestionID:int;
In my datagrid I use a change handler (line 539):
change="setQuestionID();"
We set the variable in the setQuestionID function (lines 400-407):
[Bindable (event="questionChange")]
private function setQuestionID():void
{
myQuestionID = questionsDG.selectedItem.QuestionID;
dispatchEvent(new Event("questionChange"));
}
And then try to use it in my uploader script (lines 448-475):
// initUploader is called when account info loads
public function getSessionInfoResult(event:ResultEvent):void{
// Get jsessionid & questionid (final directory) for CF uploader
myToken = roAccount.getSessionToken.lastResult;
// BUG: myQuestion is null in actionscript, but okay in form.
var postVariables:URLVariables = new URLVariables();
postVariables.jsessionid = myToken;
postVariables.questionid = myQuestionID;
multiFileUpload = new MultiFileUpload(
filesDG,
browseBTN,
clearButton,
delButton,
upload_btn,
progressbar,
uploadDestination,
postVariables,
350000,
filesToFilter
);
multiFileUpload.addEventListener(Event.COMPLETE,uploadsfinished);
}
I can see in my MXML that the value binded (line 639):
<mx:Label text="{myDirectory}"/>
and it updates when I click a row in my datagrid. However, if I try to access this myQuestionID value inside any action script it will show as null (0). I know my uploader is working as I can hardcode myDirectory to a known directory and it will upload okay.
I'm really stumped.
The reason questionid = null is that getSessionInfoResult() is called by your init code before the bound value of myQuestionID is set.
So your file uploader (multiFileUpload) is already instantiated with myQuestionID = null.
You need to instantiate/pass the value into the multiFileUpload component after it is set.
Use dataGrid change event to set myDirectory everytime the selection has changed by user. this will update the value of myDirectory properly.
By making someID as Bindable would mostly solve your problem if you dont want to use change event on DG